第6章 樹(Tree)
樹(Tree)是n (n>=0)個結點的有限集。 n=0時稱爲空樹。在任意一棵非空樹中:
1)有且僅有一個特定的稱爲根(Root)的結點;
2)當n>1時,其餘結點可分爲m(m>0)個互不相交的有限集T1、T2、……、Tm,其中每一個集合本身又是一棵樹,並且稱爲根的子樹(SubTree)。
二叉樹(Binary Tree)是n (n>=0)個結點的有限集合,該集合或者爲空集(稱爲空二叉樹),或者由一個根結點和兩棵互不相交的、分別稱爲根結點
的左子樹和右子樹的二叉樹組成。
/* 二叉樹的二叉鏈表結點結構定義 */
typedef struct BiTNode /* 結點結構 */
{
TElemType data; /* 結點數據 */
struct BiTNode *lchild, *rchild; /* 左右孩子指針 */
} BiTNode, *BiTree;
二叉樹的遍歷(traversing binary tree)是指從根結點出發,按照某種次序依次訪問二叉樹中所有結點,使得每個結點被訪問一次且僅被訪問一次。
二叉樹遍歷方法包括:
1、前序遍歷
/* 二叉樹的前序遍歷遞歸算法 */
void PreOrderTraverse(BiTree T)
{
if ( T==NULL )
return;
printf("%c",T->data); /* 顯示結點數據,可以更改爲其他對結點操作 */
PreOrderTraverse(T->lchild); /* 再先序遍歷左子樹 */
PreOrderTraverse(T->rchild); /* 最後先序遍歷右子樹 */
}
2、中序遍歷
/* 二叉樹的中序遍歷遞歸算法 */
void InOrderTraverse(BiTree T)
{
if ( T==NULL )
return;
InOrderTraverse(T->lchild); /* 中序遍歷左子樹 */
printf("%c",T->data); /* 顯示結點數據,可以更改爲其他對結點操作 */
InOrderTraverse(T->rchild); /* 最後中序遍歷右子樹 */
}
3、後序遍歷
/* 二叉樹的後序遍歷遞歸算法 */
void PostOrderTraverse(BiTree T)
{
if ( T==NULL )
return;
PostOrderTraverse(T->lchild); /* 先後序遍歷左子樹 */
PostOrderTraverse(T->rchild); /* 再後序遍歷右子樹 */
printf("%c",T->data); /* 顯示結點數據,可以更改爲其他對結點操作 */
}
4、層序遍歷
層序遍歷書中沒有附上算法,整理結果如下。
層序遍歷算法中採用了隊列(FIFO)方式實現,關於隊列的實現這裏不細說。
/* 二叉樹的層序遍歷遞歸算法 */
void LayerOrderTraverse(BiTree T)
{
if ( T==NULL )
return;
BiTree *x;
Queue Q; /* 定義隊列Q */
InitQueue(&Q); /* 初始化隊列Q */
EnQueue(&Q,T); /* 將根結點入列 */
while(! QueueEmpty(Q)) /* 若隊列非空 */
{
DeQueue(&Q, x); /* 將隊列中元素出列,並賦值給x */
printf("%c",(*x)->data); /* 顯示結點數據,可以更改爲其他對結點操作 */
if ((*x)->lchild)
EnQueue(&Q,(*x)->lchild); /* 左子樹非空,則將左子樹入列 */
if ((*x)->rchild)
EnQueue(&Q,(*x)->rchild); /* 右子樹非空,則將右子樹入列 */
}
}