二叉树的遍历

二叉树的遍历

  • 先序遍历的非递归遍历算法
  • 中序遍历的非递归遍历算法
  • 后序遍历的非递归遍历算法

先序遍历的非递归遍历算法

void InOrderTraversal(BinTree BT)
{
    BinTree T = BT;
    Stack S = CreateStack(MaxSize);
    while(T||!IsEmpty(S)){
        while(T){
        Push(S,T);
        printf("%5d",T->Data);
        T = T->Left;
        }
        if(!IsEmpty(S)){
            T = Pop(s);
            T =T->Right;
        }
    }
}

中序遍历的非递归遍历算法

void InOrderTraversal(BinTree BT)
{
    BinTree T = BT;
    Stack S = CreateStack(MaxSize);
    while(T||!IsEmpty(S)){
        while(T){
        Push(S,T);
        T = T->Left;
        }
        if(!IsEmpty(S)){
            T = Pop(s);
            printf("%5d",T->Data);
            T =T->Right;
        }
    }
}

后序遍历的非递归遍历算法

这是一个大神的想法。在此记录。

enum State {start,return_from_left,return_from_right};
//以两次递归调用作为划分,将函数状态划为3类
//还未递归调用自己,将左子树作为参数递归调用并返回后,将右子树作为参数递归调用并返回后
typedef struct {
    enum State state;
    BinTree T;
} StackElem;
//省略栈的实现

//后序遍历非递归
void PostOrderTraversal (BinTree BT)
{
    //item为当前执行的“函数”信息,栈中都是没有执行完的
    StackElem item={start,BT};
    Stack S=CreatStack(MaxSize);
    while (true){
        //退出条件:需要返回上层时栈为空
        if (item.T){
            if (item.state==start){
                //当前入栈并递归左子树
                Push(S,item);
                item.T=item.T->left;
                item.state=start;
            }
            else if (item.state==return_from_left){
                //当前入栈并递归右子树
                Push(S,item);
                item.T=item.T->right;
                item.state=start;
            }
            else{
                //item.state==return_from_right
                printf("%d",item.T->Data);

                //返回上一层
                if (!IsEmpty(S)){
                    item=Pop(S);
                    item.state++;   
                }
                else{
                    //退出
                    break;
                }
            }   
        }
        else{
            if (!IsEmpty(S)){
                item=Pop(S);
                item.state++;
            else{
                //退出
                break;
            }
        }

    }       
}

精彩之处,在于引用了一个状态量,用于记录函数的状态,记录第几次经过结点,在第三次经过结点的时候,将结点打印出来。

你可能感兴趣的:(二叉树非递归遍历,链表,二叉树,遍历,算法)