树的非递归遍历

中序遍历的几种情况

分析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;
        }
    }
}
  • 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值