树的非递归调用遍历(中序遍历)

本文讲的是非递归调用的中序遍历,如果想知道递归调用的中序遍历可以看我的另一篇博文

分析:

1、访问顺序

     中序遍历是当左子树为空或者左子树已经访问完毕以后,在访问根节点。访问完根节点在访问右子树。

2、选择什么类型的数据结构(栈?队列?)

     因为先走到的后访问,后走到的先访问,所以很显然是栈结构。

3、节点所有路径的情况

     步骤1、如果节点有左子树,该节点入栈。

                   如果没有左节点,访问该节点。

     步骤2、如果节点有右子树,重复步骤1.

                  如果没有右子树,根据栈顶元素回退,并访问栈顶元素,在访问右子树,重复步骤1.

                  如果栈为空,表示遍历结束。

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

下面看一下实现过程:

BiTNode * left(BiTNode *root, stack<BiTNode *> &s)
{//一直找左节点  找到没有左节点的节点
    if (root == NULL)
    {
        return NULL;
    }
    while(root->lchild != NULL)
    {
        s.push(root);
        root = root->lchild;
    }
    
    return root;
}

void inOrder1(BiTNode *root)
{
    BiTNode *tmp = NULL;
    stack<BiTNode *> s;
    tmp = left(root, s);
    
    while (tmp)
    {
        printf("%d ", tmp->data);
        if (tmp->rchild != NULL)//判断有没有右节点
        {
            tmp = left(tmp->rchild, s);
        }
        else if (!s.empty())//判断栈是否为空  为空则表示已经遍历结束了
        {
            tmp = s.top();
            s.pop();
        }
        else
        {
            tmp = NULL;
        }

    }
}

void main()
{
    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.rchild = &t4;
    t3.lchild = &t5;
    printf("inorder: ");
    inOrder(&t1);
    
    printf("\n");
    printf("inorder1: ");
    inOrder1(&t1);
    system("pause");
}

猜你喜欢

转载自blog.csdn.net/qianyayun19921028/article/details/81154686