二叉樹(C語言)
1、二叉樹的結構
二叉樹是由一個儲存資料的變數和兩個指向子樹的指標構成的,定義在一個結構體中。其一般形式為:
typedef struct BiTree
{
char data;
struct BiTree *lchild;
struct BiTree *rchild;
}BiTree,*BiNode;
BiNode即結構體變數的指標,BiTree是結構體變數。在建立二叉樹時,為每個結點動態分配記憶體時要用到這兩個識別符號,例如: BiNode root=(BiNode)malloc(sizeof(BiTree))。
2、二叉樹的建立
二叉樹一般使用遞迴的方式建立,遞迴呼叫函式來建立自己的左右子樹。
BiNode create()//先序建立二叉樹
{
BiNode T;
char a;
scanf("%c",&a);
if(a=='.') return NULL;//當輸入.時表示這個結點為空,而且沒有左右子樹。
else
{
T=(BiNode)malloc(sizeof(BiTree));//動態分配記憶體
T->data=a;
T->lchild=create();//建立左子樹
T->rchild=create();//建立右子樹
}
return T;
}
若想中序或後序建立,則只需改變函式中 T->data=a; T->lchild=create(); T->rchild=create(); 這三條語句的順序,先給T->data=a在先的話是先序,在中間的話是中序,在最後的話是後序。
3、二叉樹的遍歷
二叉樹一般有4種遍歷方法,即先序、中序、後序、層序。
先序的遍歷順序是根節點->左子樹->右子樹。
中序的遍歷順序是左子樹->根節點->右子樹。
後序的遍歷順序是右子樹->根節點->左子樹。
層序的遍歷順序是按層順次遍歷。
先序、中序、後序的程式碼基本相同
void pre(BiNode root)//先序遍歷二叉樹 { if(root) { printf("%c ",root->data); pre(root->lchild); pre(root->rchild); } } void mid(BiNode root)//中序遍歷二叉樹 { if(root) { mid(root->lchild); printf("%c ",root->data); mid(root->rchild); } } void post(BiNode root)//後序遍歷二叉樹 { if(root) { post(root->lchild); post(root->rchild); printf("%c ",root->data); } }
例如這個簡單的二叉樹:
當我們先序建立二叉樹時,應輸入:ABDF..GH..I..E..C..,這三種遍歷的結果為:
而層序遍歷較為複雜,可以用佇列來實現,佇列的特點是先進先出。我們先構造一個佇列,先將根節點入佇列,之後每個出佇列的結點都要判斷其左右子樹是否存在,若存在則入佇列。程式碼如下:
void level(BiNode root)//二叉樹的層次遍歷,運用佇列,每層的結點挨個先進先出。
{
BiNode queue[20],pTemp;
int cur=0,pre=0;//cur表示當前入佇列的結店,pre表示當前出佇列的結點
queue[cur++]=root;
while(cur!=pre)
{
pTemp=queue[pre++];
printf("%c ",pTemp->data);
if(pTemp->lchild!=NULL) queue[cur++]=pTemp->lchild;
if(pTemp->rchild!=NULL) queue[cur++]=pTemp->rchild;
}
}
層序遍歷上面的二叉樹的執行結果為:
4、特殊二叉樹
1、二叉排序樹
二叉排序樹的特點是:若一個結點的左子樹非空,則左子樹的值一定小於結點的值;若一個節點的右子樹非空,則右子樹的值一定大於結點的值。
例如這顆簡單二叉排序樹:
其建立過程也不復雜,對於每個資料,都判斷它與根節點的大小關係,若大於根節點,則作為根節點的右子樹,若小於根節點,則作為根節點的左子樹。則二叉排序樹的中序遍歷一定是嚴格遞增的。程式碼如下:
BiNode BSTInsert(BiNode T,int key)
{
if(!T)//若為空,則建立這個結點
{
T=(BiNode)malloc(sizeof(BiTree));
T->data=key;
T->lchild=T->rchild=NULL;
}
else
{
if(T->data<key)
T->rchild=BSTInsert(T->rchild,key);
else if(T->data>key)
T->lchild=BSTInsert(T->lchild,key);
}
return T;
}
BiNode Insert(BiNode T,int data[],int n)
{
int i;
for(i=0;i<n;i++)
T=BSTInsert(T,data[i]);
return T;
}
int main()
{
int num[9]={8,3,10,13,14,1,6,7,4};
BiNode T=NULL;
T=Insert(T,num,9);
printf("\n中序遍歷:");
mid(T);
return 0;
}
將一個數組{8,3,10,13,14,1,6,7,4}作為資料構造一棵二叉排序樹,可以得到上圖中的結果,對他進行中序遍歷的結果為:
得到了正確的結果。