二叉树的遍历原理

一、递归过程:

1、先序遍历

void xian(NODE *t)
{
    if(t)
    {
        printf("%c",t->data);
        xian(t->lson);
        xian(t->rson);
    }
}

2、中序遍历

void mid(NODE *t)
{
    if(t)
    {
        mid(t->lson);
        printf("%c",t->data);
        mid(t->rson);
    }
}

3、后序遍历

void hou(NODE *t)
{
    if(t)
    {
        hou(t->lson);
        hou(t->rson);
        printf("%c",t->data);
    }
}

遍历过程分析:
先序,中序,后序遍历过程:遍历过程中经过的路线一样,只是访问各节点的时机不同。
图中在从入口到出口的曲线上用ⓧ,☆,△三种符号分别表示先序,中序,后序访问各节点的时刻。
二叉树的遍历原理_第1张图片

二、非递归遍历:

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

代码展示
二叉树的遍历原理_第2张图片
先序遍历
在中序遍历代码的基础上把输出的语句放在Push(S,T);的后面;
二叉树的遍历原理_第3张图片
后序遍历

void PostOrderTraversal(BinTree BT) {
    BinTree T = BT, PrePop = NULL; //PrePop记录上一个Pop出来的结点
    Stack S = CreatStack(MaxSize);
    while (T || !IsEmpty(S)) {
        while (T) {        //一直向左将结点压入堆栈
            Push(S, T);
            T = T->Left;
        }
        //将Pop的过程改为循环
        while (!IsEmpty(S)) { //后序遍历有两种情况可以Pop该结点
            T = Pop(S);
            if (T->Right == PrePop || T->Right == NULL)//该结点的右结点为空或者上一次Pop的是该结点的右结点
            {  
                printf("%05d", T->Data);
                PrePop = T;
            }
            else {  //若不满足以上两种情况 说明该节点右侧节点还未被Pop
                Push(S, T);  //则将该结点重新压回堆栈
                T = T->Right;  //然后指向该结点的右节点
                break; //退出Pop循环
            }
        }
    }
}

你可能感兴趣的:(树,数据结构)