数据结构MOOC|二叉树的遍历

课程内容来自:http://www.icourse163.org/learn/ZJU-93001?tid=1002654021#/learn/content?type=detail&id=1003620984&cid=1004311357&replay=true

二叉树遍历的核心问题:二维结构(树)的线性化(线性序列)

  • 从当前结点访问其左右儿子结点;
  • 访问了左儿子后,如何访问右儿子?

    需要一个存储结构保存暂时访问不到的结点(如右儿子或该结点自己)

    存储结构:堆栈、队列

【二叉树的非递归遍历】

非递归算法实现的基本思路:利用堆栈

中序遍历非递归算法:

  1. 遇到一个结点,就将其压栈,并遍历其左子树;
  2. 当左子树遍历结束时,从栈顶弹出这个结点并访问它;
  3. 然后按其右指针再去中序遍历该结点的右子树。


序号

栈内元素

扫描二维码关注公众号,回复: 1118366 查看本文章

操作

输出序列

1

A

PUSH

NULL

2

BA

PUSH

NULL

3

DBA

PUSH

NULL

4

BA

POP

D

5

A

POP

DB

6

FA

PUSH

DB

7

EFA

PUSH

DB

8

FA

POP

DBE

9

A

POP

DBEF

10

NULL

POP

DBEFA

10

C

PUSH

DBEFA

12

GC

PUSH

DBEFA

13

C

POP

DBEFAG

14

HC

PUSH

DBEFAG

15

C

POP

DBEFAGH

16

NULL

POP

DBEFAGHC

17

I

PUSH

DBEFAGHC

18

NULL

POP

DBEFAGHCI


//中序遍历的非递归实现
void InOrderTraversal( BinTree BT){
    BinTree T = BT;
    Stack S = CreatStack( MaxSize );
    while( T || !IsEmpty(S)){
            while(T){
                Push(S,T);
                T = T->Left;
            }
            if(!IsEmpty(S)){
                T = Pop(S);
                cout<<T->Data<<endl;
                T = T->Right;
                }
    }
}
//先序遍历的非递归实现
void InOrderTraversal( BinTree BT){
    BinTree T = BT;
    Stack S = CreatStack( MaxSize );
    while( T || !IsEmpty(S)){
            while(T){
                Push(S,T);
                cout<<T->Data<<endl;
                T = T->Left;
            }
            if(!IsEmpty(S)){
                T = Pop(S);
                T = T->Right;
                }
    }
}

【层序遍历】

基本思路:利用队列

层序遍历算法:

  1. 从队列中取出一个元素;
  2. 访问该元素所指结点;
  3. 若该元素所指结点的左右儿子结点非空,则将其左右儿子的指针顺序入队。

序号

队列元素

输出序列

1

A

NULL

2

BC

A

3

CDF

AB

4

DFGI

ABC

5

FGI

ABCD

6

GIE

ABCDF

7

IEH

ABCDFG

8

EH

ABCDFGI

9

H

ABCDFGIE

10

NULL

ABCDFGIEH

void LevelOrderTraversal( BinTree BT)
{
    Queue Q;
    BinTree T;
    if( !BT ) return;
    Q = CreatQueue( MaxSize );
    AddQ( Q,BT );
    while( !IsEmptyQ( Q )){
        T = DeleteQ( Q );
        cout<<T->Data<<endl;
        if( T->Left ) AddQ( Q,T->Left );
        if( T->Right ) AddQ( Q,T->Right );
    }
}

【应用】

1.输出二叉树中的叶子结点

//在二叉树的遍历算法中增加检测结点的“左右子树是否都为空”
void PreOrderPrintLeaves( BinTree BT )
{
    if( BT ){
        if( !BT->Left && !BT->Right )
            cout<<BT->Data<<endl;
        PreOrderPrintLeaves( BT->Left );
        PreorderPrintLeaves( BT->Right );
    }
}

2.求二叉树的高度(Height=max(H1,H2)+1)


int PostOrderGetHeight( BinTree BT )
{
    int HL, HR, MaxH;
    if( BT ){
        HL = PostOrderGetHeight( BT->Left );
        HR = PostOrderGetHeight( BT->Right );
        MaxH = ( HL > HR )? HL: HR;
        return ( MaxH+1 );
    }
    else return 0;
}

3.二元运算表达式树及其遍历


4.前/后序遍+中序遍历,可以唯一确定一棵树;但前序遍历+后序遍历不可唯一确定一棵树。



如上图,中序遍历可以将左右子树分隔开来。诶呦中序则无法确定左右,如下图:


猜你喜欢

转载自blog.csdn.net/darlingwood2013/article/details/80443204