无栈非递归中序遍历非线索化二叉树

数据结构与算法 同时被 2 个专栏收录
10 篇文章 0 订阅
3 篇文章 0 订阅

试设计一个非递归算法,按中根顺序遍历非线索二叉树,但不得用任何辅助。
在执行算法期间,允许改变LLINK和RLINK的值。

 

如何不用辅助栈非递归遍历二叉树呢?
这里给出了一个比较方便的算法,其基本思路是依次将每个结点p左子树的最右结点指向p,
不停回溯,用类似右线索化的方式中序遍历二叉树。

 

具体算法如下所示:

 

1. 若p有左儿子:                          将其左儿子的最右结点(可为左儿子本身)指向p,然后p=p->lchild;

    若p无左儿子或p已经被访问:   p向上回溯(即p=p->rchild),访问p;并恢复回溯所用指针;

 

2.重复上述操作直至二叉树访问完毕。

 

 

实现方式如下图:

 

 

 

                                                   

1.从结点P开始算法                                                          2.P有左儿子,将P左子树最右结点指向P   

                         

                                        

3.P=P->lchild,P仍有左儿子,同上图操作                  4.P=P->lchild,P仍有左儿子,同上图   

 

                                                

5.P=P->lchild,P无左儿子,访问元素6                       6. P左儿子右指针指向P,说明元素6已

P=P->rchild                                                                           访问,则释放元素6指向4的指针,并访问4

 

 

                                                                               

7. P左儿子右指针指向P,说明元素4已访问,         8.P有右儿子,故P=P->rchild,访问元素5                  

     则释放元素4指向2的指针,并访问元素2                                                                                                             

 

                                          

 9.P无左儿子,故P=P->rchild,访问元素1                10.P=P->rchild,访问元素3 

 释放元素5指向元素1的指针

 

 

11.访问完毕

 

 

具体代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct BinaryTree{
int data;
struct BinaryTree* lchild ;
struct BinaryTree* rchild ;
}BT;
BT* create(int d,BT*l,BT*r);
void traverse(BT *p);

int main()
{
    BT*t6=create(6,NULL,NULL);
    BT*t5=create(5,NULL,NULL);
    BT*t4=create(4,t6,NULL);
    BT*t3=create(3,NULL,NULL);
    BT*t2=create(2,t4,t5);
    BT*t1=create(1,t2,t3);
    traverse(t1);
    return 0;
}

BT* create(int d,BT*l,BT*r)
{
    BT*p=(BT *)malloc(sizeof(BT));
    if(!p) {printf("No enough money to allocate!\n");return NULL;}
    p->data=d;
    p->lchild=l;
    p->rchild=r;
    return p;
}

void traverse(BT *p)
{
    while(p)
    {
        BT *pleft=p->lchild;
        if(pleft)
        {
            while(pleft->rchild && pleft->rchild!=p) {pleft=pleft->rchild;}
            if(!pleft->rchild)
            {
                pleft->rchild=p;
                p=p->lchild;
                continue;
            }
            else {pleft->rchild=NULL;}
        }
        printf("%d   ",p->data);
        p=p->rchild;
    }
    printf("\n");
}

 

  • 7
    点赞
  • 2
    评论
  • 10
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值