鱼C论坛

 找回密码
 立即注册
查看: 3818|回复: 3

线索二叉数中序非递归求助

[复制链接]
发表于 2021-4-11 17:46:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

【求助帖】请及时确认最佳答案,下次提问时可以得到更多关注,问题可以更快解决
include<stdio.h>
#include<stdlib.h>

#define OK 1
#define ERROR -1

typedef char TElemType;#

typedef int Status;

//线索存储标志位
//Link(0):表示指向左右孩子结点的指针
//Thread(1):表示指向前驱后继的线索
typedef enum {Link,Thread} PionterTag;


typedef struct BiThrNode
{
    TElemType data;
    struct BiThrNode *lchild,*rchild;
    PionterTag ltag;
    PionterTag rtag;

}BiThrNode,*BiThrTree;



Status CreateBiThrTree(BiThrTree &T);

void InThreading(BiThrTree T);

void Visist(char ch);

void InOrderThreading(BiThrTree &p,BiThrTree T);

void InOrderTraverse_Thr(BiThrTree T);




//全局变量,始终指向刚刚访问过的结点
BiThrTree pre;

//创建一棵二叉树,预定前序遍历输入数据
Status CreateBiThrTree(BiThrTree &T)
{
    char ch;

    scanf("%c",&ch);

    if('@' == ch)
    {
        T = NULL;
    }
    else
    {
        if(!(T = (BiThrNode*)malloc(sizeof(BiThrNode))))
            return ERROR;

        T->data = ch;
        //初始化
        T->ltag = Link;
        T->rtag = Link;


        //递归调用创建子树
        CreateBiThrTree(T->lchild);
        CreateBiThrTree(T->rchild);
    }


    return OK;

}

//中序遍历线索化
void InThreading(BiThrTree T)
{
    if( T )
    {
        InThreading(T->lchild);  //递归左孩子线索化


        /*
            结点处理
        */

        Visist(T->data);


        if( !T->lchild )//没有左孩子时让它指向前驱(即刚访问过的结点)
        {
            T->ltag = Thread; //标志tag为线索
            T->lchild = pre;
        }

        if( !pre->rchild )//前驱没有右孩子的时候,让它指向它的后继即当前这个结点
        {
            pre->rtag = Thread;
            pre->rchild = T;
        }

        pre = T;//更新结点

        InThreading(T->rchild);  //递归右孩子线索化


    }
}


//中序遍历线索化
void InOrderThreading(BiThrTree &p,BiThrTree T)
{
    /*
        p为头结点,指向根结点
    */
    p = (BiThrTree)malloc(sizeof(BiThrNode));

    p->ltag = Link;//指向头结点的指针
    p->rtag = Thread;//作为线索
    p->lchild = p;
    p->data = '%';

    if( !T )
    {
        p->lchild = p;
    }
    else
    {
        p->lchild = T;

        //初始化pre
        pre = p;

        InThreading(T);

        /*
            收尾工作,
            即若
            前序遍历结果为:A B C D E F
            中序遍历结果为: C B D A E F
            在中序的线索化遍历结束后F要指向我们的p(头结点)
        */


        pre->rchild = p;
        pre->rtag = Thread;

        p->rchild = pre;


    }
}

void Visist(char ch)
{
    printf("%c ",ch);
}

//中序遍历二叉树,非递归
void InOrderTraverse_Thr(BiThrTree T)
{

    //T 为头结点
    BiThrTree p;
    p = T->lchild;

    while( p != T)
    {

       // printf("111\n");


        while(p->ltag == Link)
        {
            p = p->lchild;
        }



        Visist(p->data);

        while(p->rtag == Thread && p->rchild !=T)
        {
            p = p->rchild;
            Visist(p->data);
        }

        p = p->rchild;


    }
}

int main()
{

    BiThrTree p=NULL,T = NULL;

    CreateBiThrTree(T);


    printf("中序遍历,并且线索化该二叉树:  \n");


    InOrderThreading(p,T);

     printf("\n\n\n");


    printf("中序遍历(非递归实现)结果为:  \n");


    InOrderTraverse_Thr(p);

    printf("\n\n\n");

    return 0;
}
https://blog.csdn.net/qq_33883389/article/details/81784409这是代码的原帖子

整个语言大部分都理解,但问题在标红字的地方,请问在语句while(p->rtag == Thread && p->rchild !=T)中为什么需要有p->rtag == Thread?
我认为如果这样写的话走到有右孩子的结点就走不下去了(即我觉得不是所有结点rtag都是thread,这样走走不全)
想了很久也没想出来,万分感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-26 18:21:56 | 显示全部楼层

回帖奖励 +1 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-4-1 22:16:56 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-4-8 17:49:21 | 显示全部楼层

回帖奖励 +1 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 12:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表