輸出二叉樹中的結點 |
【算法思想】
輸出二叉樹中的結點並無次序要求,因此可用三種遍歷算法中的任何一種完成,只需將訪問操作具體變爲輸出操作即可。下面給出採用先序遍歷實現的算法。
【算法描述】
void PreOrder(BiTree root)
/* 先序遍歷輸出二叉樹結點, root 爲指向二叉樹根結點的指針 */
{
if (root != NULL)
{
printf("%c", root->data); /* 輸出根結點 */
PreOrder(root->LChild); /* 先序遍歷左子樹 */
PreOrder(root->RChild); /* 先序遍歷右子樹 */
}
}
輸出二叉樹中的葉子結點 |
【算法思想】
輸出二叉樹中的葉子結點與輸出二叉樹中的結點相比,它是一個有條件的輸出問題,即在遍歷過程中走到每一個結點時需進行測試,看是否滿足葉子結點的條件。
【算法描述】
void PreOrder(BiTree root)
/* 先序遍歷輸出二叉樹中的葉子結點 , root 爲指向二叉樹根結點的指針 */
{
if (root != NULL)
{
if (root->LChild == NULL && root->RChild == NULL)
printf("%c", root->data); /* 輸出葉子結點 */
PreOrder(root->LChild); /* 先序遍歷左子樹 */
PreOrder(root->RChild); /* 先序遍歷右子樹 */
}
}
統計葉子結點數目 |
- 方法一
【算法思想】
統計二叉樹中的葉子結點數目並無次序要求,因此可用三種遍歷算法中的任何一種完成,只需將訪問操作具體變爲判斷是否爲葉子結點及統計操作即可。
【算法描述】
/* LeafCount 爲保存葉子結點數目的全局變量,調用之前初始化值爲 0 */
void leaf(BiTree root)
{
if (root != NULL)
{
leaf(root->LChild);
leaf(root->RChild);
if (root->LChild == NULL && root->RChild == NULL)
LeafCount++;
}
}
- 方法二
【算法思想】
給出求葉子點數目的遞歸定義:
1)如果是空樹,返回 0;
2)如果只有一個結點,返回 1;
3)否則爲左右子樹的葉子結點數之和。
【算法描述】
int leaf(BiTree root)
{
int LeafCount;
if (root == NULL)
LeafCount = 0;
else if ((root->LChild == NULL) && (root->RChild == NULL))
LeafCount = 1;
else /* 葉子數爲左右子樹的葉子數目之和 */
LeafCount = leaf(root->LChild) + leaf(root->RChild);
return LeafCount;
}
建立二叉鏈表方式存儲的二叉樹 |
- 給定一棵二叉樹,我們可以得到它的遍歷序列;
- 反過來,給定一棵二叉樹的遍歷序列,我們也可以創建相應的二叉鏈表。
這裏所說的遍歷序列是一種“擴展的遍歷序列”。在通常的遍歷序列中,均忽略空子樹,而在擴展的遍歷序列中,必須用特定的元素表示空子樹。例如,圖中二叉樹的“擴展先序遍歷序列”爲:AB.DF…G…C.E.H… 其中用小圓點表示空子樹。
【算法思想】
採用類似先序遍歷的遞歸算法,首先讀入當前根結點的數據,如果是“.”則將當前樹根置爲空,否則申請一個新結點,存入當前根結點的數據,分別用當前根結點的左子域和右子域進行遞歸調用,創建左、右子樹。
【算法描述】
void CreateBiTree(BiTree *bt)
{
char ch;
ch = getchar();
if (ch == '.')
*bt = NULL;
else
{
*bt = (BiTree)malloc(sizeof(BiTNode));
(*bt)->data = ch;
CreateBiTree(&((*bt)->LChild));
CreateBiTree(&((*bt)->RChild));
}
}
求二叉樹的高度 |
二叉樹的高度(深度)爲二叉樹中結點層次的最大值,也可視爲其左、右子樹高度的最大值加 1。
【算法思想】
二叉樹 bt 高度的遞歸定義如下
- 若 bt 爲空,則高度爲 0。
- 若 bt 非空,其高度應爲其左、右子樹高度的最大值加 1,如下圖所示。
【算法描述】
int PostTreeDepth(BiTree bt) /* 後序遍歷求二叉樹 bt 高度的遞歸算法 */
{
int hl, hr, max;
if (bt != NULL)
{
hl = PostTreeDepth(bt->LChild); /* 求左子樹的深度 */
hr = PostTreeDepth(bt->RChild); /* 求右子樹的深度 */
max = hl > hr ? hl : hr; /* 得到左、右子樹深度較大者*/
return (max + 1); /* 返回樹的深度 */
}
else
return (0); /* 如果是空樹,則返回 0 */
}
求二叉樹的高度是也可用前序遍歷的方式實現。
【算法思想】
二叉樹的高度(深度)爲二叉樹中結點層次的最大值。設根結點爲第一層的結點,所有 h 層的結點的左、右孩子結點在 h+1 層。故可以通過遍歷計算二叉樹中的每個結點的層次,其中最大值即爲二叉樹的高度。
【算法描述】
void PreTreeDepth(BiTeee bt, int h)
/* 先序遍歷求二叉樹 bt 高度的遞歸算法,h 爲 bt 指向結點所在層次,初值爲 1*/
/*depth 爲當前求得的最大層次,爲全局變量,調用前初值爲 0 */
{
if (bt != NULL)
{
if (h > depth)
depth = h; /*如果該結點層次值大於 depth,更新 depth的值*/
PreTreeDepth(bt->Lchild, h + 1); /* 遍歷左子樹 */
PreTreeDepth(bt->Rchild, h + 1); /* 遍歷右子樹 */
}
}
按樹狀打印二叉樹 |
【算法思想】
(1)二叉樹的橫向顯示應是二叉樹豎向顯示的 90。旋轉。分析上圖示可知,這種樹形打印格式要求先打印右子樹,再打印根,最後打印左子樹,按由上而下順序看,其輸出的結點序爲:CFEADB,這恰爲逆中序順序。解決二叉樹的橫向顯示問題採用“逆中序”遍歷框架,所以橫向顯示二叉樹算法爲先右子樹、再根結點、再左子樹的 RDL 結構。
(2)在這種輸出格式中,結點的左、右位置與結點的層深有關,故算法中設置了一個表示當前根結點層深的參數,以控制輸出結點的左、右位置,每當遞歸進層時層深參數加 1。這些操作應在訪問根結點時實現。
【算法描述】
void PrintTree(BiTree bt, int nLayer)
/* 按豎向樹狀打印的二叉樹 */
{
if (bt == NULL)
return;
PrintTree(bt->RChild, nLayer + 1);
for (int i = 0; i < nLayer; i++)
printf(“ ”);
printf(“% c\n”, bt->data);
/*按逆中序輸出結點,用層深決定的左、右位置*/
PrintTree(bt->LChild, nLayer + 1);
}