1. 程式人生 > >非遞迴演算法算二叉樹的高度

非遞迴演算法算二叉樹的高度

1.方法思路:用深搜和後序遍歷結合,遍歷所有節點,記錄最大高度。時間為O(n),空間為O(max)。(自創)

程式碼如下(未測試):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

int DFS_PostOrder(BiTree T){

if(!T) return 0;//樹空,高度為0

InitStack(S);

BiTree *p=T,*r=NULL;//r為後序遍歷時的輔助指標

int num=0,max=0;//num用來跟隨程式實時記錄層數,max用來記錄最大值

while(p||!isEmpty(S)){//以下為後序遍歷略作修改

while(p){//該結點入棧並搜尋其左孩子

Push(S,p);

num++;

if(num>max) max=num;

p=p->lchild;

}

Get(S,p);

if(p->rchild&&p->rchild!=r) p=p->rchild;

//如果右孩子存在並還沒訪問,則訪問

else{

Pop(S,p);

num--;//出棧則層數減1

r=p;//r指向上一個訪問節點

p=null;

}

}

ruturn max;//返回最大高度

}

2.方法思路:用層序遍歷,這裡需要記錄每一層的第一個結點r,用於計算層數。時間為O(n),空間為結點最多的層*2。(自創)

程式碼如下(未測試):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

int TreeHeight(BiTree T){

if(!T) return 0;//樹空,高度為0

InitQuece(Q);

int max=0;//記錄樹高度

BiTree *p=T,*r=null;//r記錄每一層的第一個結點

EnQuece(Q,p);

while(!isEmpty(Q)){//尋找下一層的第一個結點

int pd=0;//判定是否找到下一層的第一個結點

while(pd=0&&!isEmpty(Q)){

DeQuece(Q,p);

if(p->lchild!=Null){

EnQuece(Q,p->lchild);

r=p->lchild;

pd=1;//已找到

}

if(p->rchild!=Null){

EnQuece(Q,p->rchild);

if(pd=0){

r=p->lchild;

pd=1;//已找到

}

}

}

if(!isEmpty(Q)) Get(Q,p);

while(r!=p&&!isEmpty(Q)){//處理該層剩餘結點的孩子結點,使其入隊

DeQuece(Q,p);

if(p->lchild!=Null){ EnQuece(Q,p->lchild);}

if(p->rchild!=Null){ EnQuece(Q,p->rchild);}

}

max++;//該層結點遍歷完畢,層數+1

}

return max;

}

3.方法思路:層次遍歷+佇列應用,設定變數level記錄當前結點所在層數,設定變數last指向當前層最後結點,每次層次遍歷出隊時與last指標比較,若兩者相等,那麼層數加1,並讓last指向下一層最右結點,至遍歷完成。level的值即為二叉樹的高度。時間為O(n),空間為O(n)。(王道書所述)

程式碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

int Btdepth(BiTree T){

//採用層次遍歷的非遞迴方法求解二叉樹的高度

if(!T) return 0;//樹空,高度為0

int front=-1,rear=-1;

int last=0,level=0;//last指向下一層第一個結點的位置

BiTree Q[MaxSize];//設定佇列Q,元素是二叉樹結點指標且容量足夠

Q[++rear]=T;//根結點入隊

BiTree p;

while(front<rear){//隊不空,則迴圈

p=Q[++front];//佇列元素出隊,則正在訪問的結點

if(p->lchild) Q[++rear]=p->lchild;//左孩子入隊

if(p->rchild) Q[++rear]=p->rchild;//右孩子入隊

if(front==last){//處理該層的最右結點

level++;//層數加1

last=rear;//last指向下層

}

}

return level;

}

4.遞迴方法

程式碼如下:

1

2

3

4

5

6

7

int Btdepth(BiTree T){

if(T==NULL) return 0;

ldep=Btdepth(T->lchild);//左子樹高度

rdep=Btdepth(T->rchild);//右子樹高度

if(ldep>rdep)    return ldep+1;//樹的高度為子樹最大高度加根結點

else    return rdep+1;

}