C++ 实现二叉树各种遍历的非递归实现

一:先序的非递归实现

void pre_order(Node* p)
{
    Node* stack[10];
    int top=-1;       //使得top直接指向栈顶
    while(p!=NULL) 
    {
        while(p->left!=NULL)
        {
            printf("%c\n",p->data);   
            stack[++top]=p;       //输出的同时入栈——节点存起来,以便左边深度回来之后往右边去
            p=p->left;
        }
        if(p->right!=NULL)     //右边不空才可以去过去
        {
            printf("%c\n",p->data);
            p=p->right;
            top--;
        }
        if(p->left==NULL&&p->right==NULL)   //要考虑到叶子节点
        {
            printf("%c\n",p->data);
            if(stack[top]->right!=NULL)
            {
                p=stack[top]->right;
                top--;
            }
            else
            {
                top--;
                while(stack[top]->right==NULL)
                {
                    top--;
                }
                p=stack[top]->right;
            }
        }
        if(top==-1)return;    //栈空时遍历结束
    }
    return;
}

二:中序非递归遍历

void mid_order(Node* p)
{
    Node* stack[10];
    int top=-1;
    while(p!=NULL)
    {
        while(p->left!=NULL)
        {
            stack[++top]=p;   //存但是不输出——中序
            p=p->left;
        }
        printf("%c\n",p->data);
        if(p->right!=NULL)p=p->right;
        else
        {
            printf("%c\n",stack[top]->data);  //中序——通过栈顶来延后输出中心
            if(stack[top]->right!=NULL)       //中心处理完后就到了右边
            {
                p=stack[top]->right;    //!!!!!
                top--;
            }
            else
            {
                top--;          //左右都没路走了,就该出栈了
                while(stack[top]->right==NULL)   //一路向北,找中序完可以往右边走的
                {
                    printf("%c\n",stack[top]->data);  //右边没得走了就退栈,继续往北走
                    top--;
                    if(top==-1)return;   //有出栈操作就要随时做是否空栈的判断()
                }
                printf("%c\n",stack[top]->data);   
                p=stack[top]->right;
                top--;
            }
            if(top==-1&&p->left==NULL&&p->right==NULL)//存在栈空,而还未遍历完的情况——p还担着责任,还不能结束
            {                                         //即root的右子树只有一个元素
                printf("%c\n",p->data);
                return;
            }
        }
    }
    return;
}

三:后序的非递归实现

void late_order(Node* p)
{
    Node* stack[10];
    int top=-1;
    while(p!=NULL)
    {
        while(p->left!=NULL)
        {
            stack[++top]=p;   //后序,遇见中心先压入栈不输出
            p=p->left;
        }
        if(p->right!=NULL)p=p->right;   //然后是右手边,如果不为空,就往右手边用循环挖
        else                            //如果右手边是空的,那就轮到中心
        {
            printf("%c\n",p->data);   //一个继续看一下输出窗口
            if(stack[top]->right!=NULL&&stack[top]->right!=p)p=stack[top]->right;//!!! 防止重复遍历死循环 
            else                                                              //栈顶的右手刚好是当前走完的节点,不应该再进去的
            {
                printf("%c\n",stack[top]->data);              
                p=stack[top];
                top--;                          //赶紧先把栈顶给踢出去
                while(p==stack[top]->right)    //不断出栈,直到不会死循环为止
                {
                    printf("%c\n",stack[top]->data);
                    p=stack[top];                //也要及时更新最新节点哦
                    top--;
                    if(top==-1)return;
                }
                while(stack[top]->right==NULL&&top>-1)
                {
                    printf("%c\n",stack[top]->data);
                    top--;
                    if(top==-1&&stack[top+1]->right==stack[top+2])return;
                }
                if(top==-1)return;
                p=stack[top]->right;
            }
        }

    }

}

四:层序

void layer_order(Node* p)
{
    Node* stack[10];
    int top=-1;
    Node* temp[10];
    int mark=-1;
    if(p!=NULL)stack[++top]=p;
    while(p!=NULL)
    {
        while(top>-1)    //空栈了再重新放入
        {
            printf("%c\n",stack[top]->data);
            if(stack[top]->left!=NULL)temp[++mark]=stack[top]->left;    //注意顺序
            if(stack[top]->right!=NULL)temp[++mark]=stack[top]->right;
            top--;
        }
        while(mark>-1)stack[++top]=temp[mark--];   //
        if(top==-1)return;
    }
}

最后再附上树的初始化:

struct Node
{
    char data;
    Node* left;
    Node* right;
};

int main()
{
    Node a,b,c,d,e,f,g,h,i,j;
    Node* root;
    a.data='a';
    b.data='b';
    c.data='c';
    d.data='d';
    e.data='e';
    f.data='f';
    g.data='g';
    h.data='h';
    i.data='i';
    j.data='j';
    root=&a;
    a.left=&b;
    a.right=&c;
    b.left=&d;
    b.right=&e;
    c.left=&f;
    c.right=&g;
    d.left=&h;
    d.right=&i;
    e.left=&j;
    e.right=NULL;
    h.left=NULL;
    h.right=NULL;
    i.left=NULL;
    i.right=NULL;
    j.left=NULL;
    j.right=NULL;
    f.left=NULL;
    g.left=NULL;
    f.right=NULL;
    g.right=NULL;
	return 0;    
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值