克己ovo 2021-10-15 21:01 采纳率: 90%
浏览 48

线索二叉树的建立与遍历 输出问题


#include<stdio.h>
#include<stdlib.h>
//线索化二叉树
//定义线索二叉树的存储结构
typedef struct ThreadNode{
    char data;     //存数据
    struct ThreadNode* Left;   //指针域 
    struct ThreadNode* Right;   //指针域 
    int Tag_Left,Tag_Right;          //标识域 
}ThreadNode,*ThreadTreeNode;  

ThreadTreeNode pre = NULL;   //辅助指针 指向刚访问的树结点 全局变量 
//线索二叉树的初始化(建立)先序建立  按顺序插入 
ThreadTreeNode InitThreadTree(ThreadTreeNode Tree){
    char ch;
    printf("请输入数据 (#表示空指针):\n");
    ch = getchar();
    getchar();                      //吃掉enter产生的空格 
    if(ch == '#') Tree = NULL;      //以#代表空 
    else{
        Tree = (ThreadTreeNode)malloc(sizeof(ThreadNode));
        Tree->data = ch;
        //此时不对标识域进行初始化 遍历的时候才对标识域进行处理 
        Tree->Left = InitThreadTree(Tree->Left);
        Tree->Right = InitThreadTree(Tree->Right);
    }
    return Tree;
}
//中序线索化 不同遍历顺序 有不同的线索化二叉树 
/*每个树结点都考虑两次 如果其左子树为空 则指向前驱 
考虑后继的时候要到下一个结点操作 如果pre不空且pre有右子树则成为pre的后继*/

/*TreeRoot为根结点指针 中序线索二叉树(不带头结点)*/
void InThreading(ThreadTreeNode TreeRoot)   //TreeRoot为根结点指针 
{
    if(TreeRoot)
    {
        InThreading(TreeRoot->Left);        /*左子树递归线索化*/
        if(TreeRoot->Left == NULL)                /*如果没有左子树*/
        {
            TreeRoot->Tag_Left = 1;            /*Tag = 1*/
            TreeRoot->Left = pre;          /*设置前驱*/
        }
        
        else TreeRoot->Tag_Left= 0;            /*有左子树  Tag = 0*/
 
        //判断当前节点的前驱节点不为空且其右子树为空,则改其右指针指向当前节点  
        if(pre != NULL && pre->Right == NULL)
        {
            pre->Tag_Right = 1;            /*设置后继*/
            pre->Right = TreeRoot;
        }
 
        else pre->Tag_Right = 0;
 
        pre = TreeRoot;                       /*记录结点 */
 
        InThreading(TreeRoot->Right);        /*右子树递归线索化*/
    }
}

/*---------带头结点的二叉树的中序线索化--------*/
void HeadNode_InitThreadTree(ThreadTreeNode &HeadNode,ThreadTreeNode TreeRoot)
{
     HeadNode = (ThreadTreeNode)malloc(sizeof(ThreadNode));  //头结点
    HeadNode->Tag_Left= 0;            /*头结点有左孩子,为根结点*/
    HeadNode->Tag_Right = 1;        /*头结点无右孩子,后继线索为中序遍历的最后一个结点*/
    
    HeadNode->Right = HeadNode;        /*初始化时后继为头结点本身*/
 
    if(!TreeRoot) HeadNode->Left = HeadNode;    /*若二叉树为空,左孩子也为头结点本身*/
 
    else
    {
        HeadNode->Left= TreeRoot;     /*头结点的作用体现,统一根结点与其他结点的处理方式*/
         pre = TreeRoot;
        InThreading(TreeRoot);            /*对二叉树中序线索化*/
 
        pre->Tag_Right = 1;                /*线索化结束后,pre为二叉树的最右结点*/
 
        pre->Left = HeadNode;            /*使其右线索指向头结点*/
                                    
        HeadNode->Right = pre;            /*将头结点的后继从它本身改为最右结点*/
    }
}

/*----------遍历中序线索二叉树----------*/
 
void Show(ThreadTreeNode HeadNode)
{/*HeadNode指向线索二叉树的头结点,而头结点的左指针指向二叉树的根结点*/
    ThreadTreeNode Woke_Ptrl = HeadNode->Left;        /*使p指向根结点*/
 
    while(Woke_Ptrl != HeadNode)                    /*若线索二叉树不为空或遍历未结束*/
    {
        while(Woke_Ptrl->Tag_Left == 0)         /*沿左孩子往下,定位*/
        Woke_Ptrl=Woke_Ptrl->Left;    
        printf("%c ",Woke_Ptrl->data);                        /*访问左子树为空的结点*/
        /*若有右线索,且右线索不为头结点*/
        while(Woke_Ptrl->Tag_Right == 1 && Woke_Ptrl->Right != HeadNode)    
        {
            Woke_Ptrl = Woke_Ptrl->Right;
            printf("%c ",Woke_Ptrl->data);                    /*沿右线索访问后继结点*/
        }
        
        Woke_Ptrl = Woke_Ptrl->Right;                /*转向p的右子树*/
    }
}
int main(){
    ThreadTreeNode HeadNode =NULL;  //头结点
    ThreadTreeNode tree = NULL;
    tree = InitThreadTree(tree);
    HeadNode_InitThreadTree(HeadNode,tree);
    printf("中序线索二叉树的输出:\n");
    Show(HeadNode);
}

  • 写回答

1条回答 默认 最新

  • qzjhjxj 2021-10-18 16:16
    关注

    修改如下,供参考:

    #include<stdio.h>
    #include<stdlib.h>
    //线索化二叉树
    //定义线索二叉树的存储结构
    typedef struct ThreadNode {
        char data;     //存数据
        struct ThreadNode* Left;   //指针域 
        struct ThreadNode* Right;   //指针域 
        int Tag_Left, Tag_Right;    //标识域 
    }ThreadNode, * ThreadTreeNode;
    ThreadTreeNode pre = NULL;   //辅助指针 指向刚访问的树结点 全局变量 
    //线索二叉树的初始化(建立)先序建立  按顺序插入 
    ThreadTreeNode InitThreadTree(ThreadTreeNode  Tree) {
        char ch;
        printf("请输入数据 (#表示空指针):\n");
        ch = getchar();
        getchar();                      //吃掉enter产生的空格 
        if (ch == '#') Tree = NULL;      //以#代表空 
        else {
            Tree = (ThreadTreeNode)malloc(sizeof(ThreadNode));
            Tree->data = ch;
            //此时不对标识域进行初始化 遍历的时候才对标识域进行处理 
            Tree->Left = InitThreadTree(Tree->Left);
            Tree->Right = InitThreadTree(Tree->Right);
        }
        return Tree;
    }
    //中序线索化 不同遍历顺序 有不同的线索化二叉树 
    //每个树结点都考虑两次 如果其左子树为空 则指向前驱
    //考虑后继的时候要到下一个结点操作 如果pre不空且pre有右子树则成为pre的后继
    //TreeRoot为根结点指针 中序线索二叉树(不带头结点)
    void InThreading(ThreadTreeNode TreeRoot)   //TreeRoot为根结点指针 
    {
        if (TreeRoot)
        {
            InThreading(TreeRoot->Left);        //左子树递归线索化
            if (TreeRoot->Left == NULL)          //如果没有左子树
            {
                TreeRoot->Tag_Left = 1;         //Tag = 1
                TreeRoot->Left = pre;          //设置前驱
            }
            else TreeRoot->Tag_Left = 0;      //有左子树  Tag = 0
                                        //判断当前节点的前驱节点不为空且其右子树为空,则改其右指针指向当前节点  
            if (pre->Right == NULL )           //&& pre->Tag_Right == NULL)//
            {
                pre->Tag_Right = 1;            //设置后继
                pre->Right = TreeRoot;
            }
            else pre->Tag_Right = 0;
            pre = TreeRoot;                       //记录结点 
            InThreading(TreeRoot->Right);        //右子树递归线索化
        }
    }
    //---------带头结点的二叉树的中序线索化--------
    void HeadNode_InitThreadTree(ThreadTreeNode& HeadNode, ThreadTreeNode TreeRoot)
    {
        HeadNode = (ThreadTreeNode)malloc(sizeof(ThreadNode));  //头结点
        HeadNode->Tag_Left = 0;            //头结点有左孩子,为根结点
        HeadNode->Tag_Right = 1;        //头结点无右孩子,后继线索为中序遍历的最后一个结点
        HeadNode->Right = HeadNode;        //初始化时后继为头结点本身
        if (!TreeRoot) HeadNode->Left = HeadNode;    //若二叉树为空,左孩子也为头结点本身
        else
        {
            HeadNode->Left = TreeRoot;     //头结点的作用体现,统一根结点与其他结点的处理方式                          
            pre = HeadNode;//pre = TreeRoot;
            InThreading(TreeRoot);            //对二叉树中序线索化
            pre->Tag_Right = 1;                //线索化结束后,pre为二叉树的最右结点
            pre->Right = HeadNode;//pre->Left = HeadNode;//使其右线索指向头结
            HeadNode->Right = pre;            //将头结点的后继从它本身改为最右结点
        }
    }
    //----------遍历中序线索二叉树----------
    void Show(ThreadTreeNode HeadNode)
    {//HeadNode指向线索二叉树的头结点,而头结点的左指针指向二叉树的根结点
        ThreadTreeNode Woke_Ptrl = HeadNode->Left;        //使p指向根结点
        while (Woke_Ptrl != HeadNode)                    //若线索二叉树不为空或遍历未结束
        {
            while (Woke_Ptrl->Tag_Left == 0)    //沿左孩子往下,定位
                Woke_Ptrl = Woke_Ptrl->Left;
            printf("%c ", Woke_Ptrl->data);     //访问左子树为空的结点
                                                //若有右线索,且右线索不为头结点
            while (Woke_Ptrl->Tag_Right == 1 && Woke_Ptrl->Right != HeadNode)
            {
                Woke_Ptrl = Woke_Ptrl->Right;
                printf("%c ", Woke_Ptrl->data);   //沿右线索访问后继结点
            }
            Woke_Ptrl = Woke_Ptrl->Right;       //转向p的右子树
        }
    }
    int main() 
    {
        ThreadTreeNode HeadNode = NULL;  //头结点
        ThreadTreeNode tree = NULL;
        tree = InitThreadTree(tree);
        HeadNode_InitThreadTree(HeadNode, tree);
        printf("中序线索二叉树的输出:\n");
        Show(HeadNode);
        return 0;
    }
    
    
    评论

报告相同问题?

问题事件

  • 创建了问题 10月15日

悬赏问题

  • ¥15 我的R语言提示去除连锁不平衡时clump_data报错,图片以下所示,卡了好几天了,苦恼不知道如何解决,有人帮我看看怎么解决吗?
  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 有偿四位数,节约算法和扫描算法
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制
  • ¥20 Vs code Mac系统 PHP Debug调试环境配置
  • ¥60 大一项目课,微信小程序