Ⅰ 二叉樹相關演算法的實驗驗證 [ 實驗目的] 驗證二叉樹的鏈接存儲結構及其上的基本操作。(c++)
淺談數據結構-二叉樹
二叉樹是樹的特殊一種,具有如下特點:1、每個結點最多有兩顆子樹,結點的度最大為2。2、左子樹和右子樹是有順序的,次序不能顛倒。3、即使某結點只有一個子樹,也要區分左右子樹。
一、特殊的二叉樹及特點
1、斜樹
所有的結點都只有左子樹(左斜樹),或者只有右子樹(右斜樹)。這就是斜樹,應用較少
基本思想:先後序遍歷左子樹,然後再後序遍歷右子樹,最後再訪問根結點即左—右—根。
圖中後序遍歷結果是:4,8,7,5,2,6,3,1。
後序遞歸遍歷代碼實現,如下所示。
//後序遞歸遍歷void PostOrderTraverse(BiTree t){ if(t != NULL) { PostOrderTraverse(t->lchild); PostOrderTraverse(t->rchild); printf("%c ", t->data); }}後序遍歷的非遞歸實現是三種遍歷方式中最難的一種。因為在後序遍歷中,要保證左孩子和右孩子都已被訪問,並且左孩子在右孩子之前訪問才能訪問根結點,這就為流程式控制制帶來了難題。下面介紹一種思路。
要保證根結點在左孩子和右孩子訪問之後才能訪問,因此對於任一結點p,先將其入棧。若p不存在左孩子和右孩子,則可以直接訪問它,或者p存在左孩子或右孩子,但是其左孩子和右孩子都已經被訪問過了,則同樣可以直接訪問該結點。若非上述兩種情況,則將p的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子之前別訪問,左孩子和右孩子都在根結點前面被訪問。
//後序非遞歸遍歷二叉樹int NoPostOrderTraverse(BiTree t){ SqStack s; InitStack(&s); BiTree cur; //當前結點 BiTree pre = NULL; //前一次訪問的結點 BiTree tmp; if(t == NULL) { fprintf(stderr, "the tree is null.
"); return ERROR; } Push(&s, t); while(IsEmpty(&s) != 1) { GetTop(&s, &cur);// if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild || pre == cur->rchild))) { printf("%c ", cur->data); //如果當前結點沒有孩子結點或者孩子結點都已被訪問過 Pop(&s, &tmp); pre = cur; } else { if(cur->rchild != NULL) { Push(&s, cur->rchild); } if(cur->lchild != NULL) { Push(&s, cur->lchild); } } } return OK;}五、二叉樹的建立
其實而二叉樹的建立就是二叉樹的遍歷,只不過將輸入內容改為建立結點而已,比如,利用前序遍歷建立二叉樹
//創建樹//按先後次序輸入二叉樹中結點的值(一個字元),#表示空樹//構造二叉鏈表表示的二叉樹BiTree CreateTree(BiTree t){ char ch; scanf("%c", &ch); if(ch == '#') { t = NULL; } else { t = (BitNode *)malloc(sizeof(BitNode)); if(t == NULL) { fprintf(stderr, "malloc() error in CreateTree.
"); return; } t->data = ch; //生成根結點 t->lchild = CreateTree(t->lchild); //構造左子樹 t->rchild = CreateTree(t->rchild); //構造右子樹 } return t;}