中序遍历的栈实现

中序遍历的几种情况

分析1:什么时候访问根、什么时候访问左子树、什么访问右子树

   当左子树为空或者左子树已经访问完毕以后,再访问根
   访问完毕根以后,再访问右子树。
  • 1
  • 2
  • 3

分析2:为什么是栈,而不是其他队列。

    先走到的后访问、后走到的先访问,显然是栈结构
  • 1
  • 2

分析3:结点所有路径情况

  • 步骤1: 
    如果结点有左子树,该结点入栈; 
    如果结点没有左子树,访问该结点;
  • 步骤2: 
    如果结点有右子树,重复步骤1; 
    如果结点没有右子树(结点访问完毕),回退,让栈顶元素出栈,访问栈顶元素,并访问栈顶元素的右子树,重复步骤1

  • 步骤3: 
    如果栈为空,表示遍历结束。

注意:入栈的结点表示,本身没有被访问过,同时右子树也没有被访问过。


/*返回的是中序遍历的起点*/
BiTNode * goLeft(BiTNode * T, stack<BiTNode*>& s)
{
    if (T == NULL)//合法性检测
    {
        return NULL;
    }

    /*如果有左子树就直接入栈*/
    while (T->lchild != NULL)
    {
        s.push(T);//入栈
        T = T->lchild;//指针指向左子树
    }

    /*没有左子树就直接访问--返回给上层应用*/
    return T;
}

void Inorder2(BiTNode * T)
{
    BiTNode * t = NULL;
    stack<BiTNode*> s;

    t = goLeft(T, s);

    while (t)
    {
        /*直接访问中序遍历的起点*/
        printf("%d\t",t->data);


        /*如果有右子树,重复步骤1*/
        if (t->rchild != NULL){
            t = goLeft(t->rchild, s);//右子树中中序遍历的起点
        }
        else if (!s.empty()){//如果没有右子树,根据栈顶元素回退
            t = s.top();//更新t为下次所用
            s.pop();
        }//如果没有右子树,而且栈为空,表示遍历结束
        else{
            t = NULL;
        }
    }
}


  • 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
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • C语言版本的非递归遍历——使用自己的链式栈实现
  • #include "linkstack.h"
    
    //二叉链表示法
    struct _bitTree
    {
        int data;
        struct _bitTree * lchild, *rchild;
    };
    
    typedef struct _bitTree BiTNode;
    typedef struct _bitTree* BiTreee;
    
    
    /*返回的是中序遍历的起点*/
    BiTNode * goLeft(BiTNode * T, LinkStack* s)
    {
        if (T == NULL)//合法性检测
        {
            return NULL;
        }
    
        /*如果有左子树就直接入栈*/
        while (T->lchild != NULL)
        {
            LinkStack_Push(s,(void*)T);//入栈
            T = T->lchild;//指针指向左子树
        }
    
        /*没有左子树就直接访问--返回给上层应用*/
        return T;
    }
    
    void Inorder2(BiTNode * T)
    {
        BiTNode * t = NULL;
        LinkStack* s = LinkStack_Create();
        if (s == NULL)
        {
            return ;
        }
    
        t = goLeft(T, s);
    
        while (t)
        {
            /*直接访问中序遍历的起点*/
            printf("%d\t",t->data);
    
    
            /*如果有右子树,重复步骤1*/
            if (t->rchild != NULL){
                t = goLeft(t->rchild, s);//右子树中中序遍历的起点
            }
            else if (LinkStack_Size(s) > 0){//如果没有右子树,根据栈顶元素回退
                t = (BiTNode*)LinkStack_Pop(s);//更新t为下次所用
                //s.pop();
            }//如果没有右子树,而且栈为空,表示遍历结束
            else{
                t = NULL;
            }
        }
    }
    
    /*先序遍历*/
    void preOrder(BiTNode * root)
    {
        /*先根节点*/
        if (root == NULL)
        {
            return;
        }
        printf("%d", root->data);
    
        /*遍历左子树*/
        preOrder(root->lchild);
    
        /*遍历右子树*/
        preOrder(root->rchild);
    }
    
    
    
    
    int main(void)
    {
        BiTNode t1, t2, t3, t4, t5;
    
        memset(&t1, 0, sizeof(BiTNode));
        memset(&t2, 0, sizeof(BiTNode));
        memset(&t3, 0, sizeof(BiTNode));
        memset(&t4, 0, sizeof(BiTNode));
        memset(&t5, 0, sizeof(BiTNode));
    
        t1.data = 1;
        t2.data = 2;
        t3.data = 3;
        t4.data = 4;
        t5.data = 5;
    
    
        t1.lchild = &t2;
        t1.rchild = &t3;
        t2.lchild = &t4;
        t3.lchild = &t5;
    
        Inorder2(&t1);
        //printf("%d\n",Depth(&t1));
    
        system("pause");
        return 0;
    }


阅读更多
换一批

没有更多推荐了,返回首页