樹
利用順序存儲和鏈式存儲的特點,可以實現樹的存儲結構的表示,具體表示法有很多種。
1)雙親表示法:在每個結點中,附設一個指示器指示其雙親結點在數組中的位置。
2)孩子表示法:把每個結點的孩子排列起來,以單鏈表作存儲結構,則n個結點有n個孩子鏈表,如果是葉子結點則此單鏈表為空。然后n個頭指針又組成一個線性表,采用順序存儲結構,存放進一個一維數組中。
3)孩子兄弟表示法:任意一棵樹,它的結點的第一個孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,可以設置兩個指針,分別指向該結點的第一個孩子和此結點的右兄弟。--------------該表示法的一大好處就是它把一棵復雜的樹變成了一棵二叉樹。
二叉樹
二叉樹(Binary Tree)是n(n>=0)個結點的有限集合,該集合或者為空集(稱為空二叉樹),或者由一個根結點和兩棵互不相交的、分別稱為根結點的左子樹和右子樹的二叉樹組成 -------------------文字描述里面已含有遞歸的思想。
特殊二叉樹:
1)斜樹:所有的結點都只有左子樹的二叉樹叫左斜樹。所有結點都是只有右子樹的二叉樹叫右斜樹。這兩者統稱為斜樹。
2)滿二叉樹:在一棵二叉樹中,如果所有分支節點都存在左子樹和右子樹,並且所有葉子都在同一層上,這樣的二叉樹稱為滿二叉樹。
3)完全二叉樹:對一棵具有 n 個結點的二叉樹按層序編號,如果編號為 i(1<=i<=n)的結點與同樣深度的滿二叉樹中編號為 i 的結點在二叉樹中位置完全相同,則這棵二叉樹稱為完全二叉樹。
遍歷二叉樹
二叉樹的遍歷(traversing bianry tree)是指從根結點出發,按照某種次序依次訪問二叉樹中所有結點,使得每個結點被訪問一次且僅被訪問一次。
1)前序遍歷:規則是若二叉樹為空,則空操作返回,否則先訪問根結點,然后前序遍歷左子樹,再前序遍歷右子樹----------------------遞歸思想
2)中序遍歷:規則是若樹為空,則空操作返回,否則從根結點開始(僅僅是開始,先不訪問該結點),中序遍歷根結點的左子樹,然后是訪問根結點(訪問),最后中序遍歷右子樹--------------------遞歸思想
3)后序遍歷:規則是若樹為空,則空操作返回,否則從左到右先葉子后結點的方式遍歷訪問左右子樹,最后是訪問根結點。
4)層序遍歷:規則是若樹為空,則空操作返回,否則從樹的第一層,也就是根結點開始訪問,從上而下逐層遍歷,在同一層中,按從左到右的順序對結點逐個訪問。
遍歷性質:
1、已知前序遍歷序列和中序遍歷序列,可以唯一確定一棵二叉樹。
2、已知后序遍歷序列和中序遍歷序列,可以唯一確定一棵二叉樹。
但注意:已知前序和后序遍歷,是不能確定一棵二叉樹的。
具體實現代碼如下:
/* BiTree.h頭文件 */
#include<iostream>
typedef char TElemType;
class BiTNode{ /*創建結點類,使用的是左右孩子表示法*/
public:
BiTNode():data(0),lchild(NULL),rchild(NULL){}
TElemType data;
BiTNode *lchild,*rchild;
};
void CreateBiTree(BiTNode **T) /*二叉樹的建立,這里形參用的是雙指針,需要注意*/
{
std::cout<<"請前序遍歷輸入各節點:"; /*這里輸入的是一個擴展二叉樹,每個結點若有空指針,*/
TElemType ch; /*則將其值設為一個特定值,本代碼中是'#'*/
std::cin>>ch;
std::cin.clear();
if(ch=='#')
*T=NULL;
else
{
*T=new BiTNode;
if(!*T)
exit(1);
(*T)->data=ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
void PreOrderTraverse(BiTNode *T) /*前序遍歷*/
{
if (T==NULL)
return;
std::cout<<T->data<<"\t";
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
void InOrderTraverse(BiTNode *T) /*中序遍歷*/
{
if (T==NULL)
return;
InOrderTraverse(T->lchild);
std::cout<<T->data<<"\t";
InOrderTraverse(T->rchild);
}
void PostOrderTraverse(BiTNode *T) /*后序遍歷*/
{
if(T==NULL)
return;
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
std::cout<<T->data<<"\t";
}
運行結果如下:

