【資料結構週週練】014 利用棧和非遞迴演算法求鏈式儲存的二叉樹是否為完全二叉樹
阿新 • • 發佈:2018-11-05
一、前言
首先,明天是個很重要的節日,以後我也會過這個節日,在這裡,提前祝所有程式猿們,猿猴節快樂,哦不,是1024程式設計師節快樂。
今天要給大家分享的演算法是判斷二叉樹是否為完全二叉樹,相信大家對完全二叉樹的概念並不陌生,如果是順序儲存就會很方便,那鏈式儲存怎麼判斷呢,我的做法是:若當前結點不為空將當前結點入棧,判斷結點是否滿足完全二叉樹,滿足返回1,p指向p的左孩子結點;否則返回0。若當前結點為空;出棧,並使p指向p的右孩子繼續遍歷,直到全部遍歷完為止。
其他思路:結合編號,從上到下,從左往右依次對結點進行編號,並判斷編號與父節點編號關係,若從0開始編號,則父節點與孩子結點的關係為 :
T->lChild == T->parent * 2 + 1
T->rChild == (T->parent + 1) * 2
只要出現不滿足,則說明不是完全二叉樹。該演算法比較簡單,大家自己嘗試做一下。
二、題目
將下圖用二叉樹存入,並判斷該樹是否為完全二叉樹。其中圓角矩形內為結點資料,旁邊數字為結點編號,編號為0的結點為根節點,箭頭指向的結點為箭尾的孩子結點。
三、程式碼
#define MAXQUEUESIZE 10 #include<iostream> #include<malloc.h> using namespace std; typedef struct BiTNode { int data; int number; struct BiTNode *lChild, *rChild, *parent; }BiTNode, *BiTree; typedef BiTree SElemType; typedef struct LNode{ SElemType data; struct LNode *next; }LNode,*LinkStack; int number = 0; int yon = 0; int yesOrNo[] = { 1,0,1,0,0,1,1,1,0,0,1,0,0,1,0,0 }; int numData[] = { 1,2,4,3,5,7,8,6 }; BiTree treeParent = NULL; int InitStack(LinkStack &S) { S = (LinkStack)malloc(sizeof(LNode)); if (!S) { cout << "空間分配失敗(Allocate space failure)" << endl; exit(OVERFLOW); } S->next = NULL; return 1; } int Push(LinkStack &S, SElemType e) { LinkStack p = (LinkStack)malloc(sizeof(LNode)); if (!p) { cout << "結點分配失敗(Allocate node failure)" << endl; exit(OVERFLOW); } S->data = e; p->next = S; S = p; return 1; } int Pop(LinkStack &S, SElemType &e) { LinkStack p = S->next; if (!p) { cout << "棧空(The stack is null)" << endl; exit(OVERFLOW); } e = p->data; S->next = p->next; free(p); return 1; } int OperationBiTree(BiTree &T) { T = (BiTree)malloc(sizeof(BiTNode)); if(!T){ cout << "空間分配失敗(Allocate space failure.)" << endl; exit(OVERFLOW); } T->number = number; T->data = numData[number]; number++; T->lChild = NULL; T->rChild = NULL; T->parent = treeParent; return 1; } void EstablishBiTree(BiTree &T) { OperationBiTree(T); treeParent = T; if (yesOrNo[yon++]) EstablishBiTree(T->lChild); treeParent = T; if (yesOrNo[yon++]) EstablishBiTree(T->rChild); } int Judge(BiTree T) { BiTree p = T; if (!p->rChild && p->lChild) { if (p->lChild || p->rChild) return 0; } else if (p->rChild && !p->lChild) return 0; else return 1; } int JudgeCompleteBiTree(BiTree T) { BiTree p = T; LinkStack S; InitStack(S); while (p||S->next) { if (p) { Push(S, p); if (Judge(p)) p = p->lChild; else return 0; } else { Pop(S, p); p = p->rChild; } } return 1; } void main() { BiTree T; EstablishBiTree(T); if (JudgeCompleteBiTree(T)) cout << "This binary tree is a complete binary tree" << endl; else cout << "This binary tree isn't a complete binary tree" << endl; }
四、實現效果
對於第二顆樹,只需要修改兩個位置,樹建立時候的兩個陣列:
int yesOrNo[] = { 1,1,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0 };
int numData[] = { 1,2,4,8,9,5,3,6,7 };
結果如下: