留个笔记

Description

建立中序线索二叉树,并按中序遍历该二叉树。

Input

输入数据有多组,对于每组测试数据
按先序遍历顺序输入二叉树的各个结点值,#表示空节点。

Output

该二叉树的中序遍历序列。

Sample Input

ABD##E##C##

Sample Output

DBEAC

感觉有点鸡肋

前置定义

char a[10000];//读取字符串
int index;//用作建树的时候控制数组下表,这里有多组样例,也不知道有什么更好的办法
typedef struct TreeNode* ptr;
#define Size sizeof(TreeNode)
struct TreeNode {char data;int ltag,rtag;//标记是线索还是指针ptr lchild, rchild;//
};

建立线索二叉树首先要建立一棵普通的二叉树,这里给出了先序遍历的序列就直接建了,就先把所有指针域的tag赋值为1了,后面还要修改的

//建立二叉树
void createTree(ptr &p) {if (index == strlen(a))return;//建完了index++;char ch = a[index];if (a[index] == '#') {p = NULL;return;}p = (ptr)malloc(Size);p->data = ch; //不要忘记填充数据p->ltag = 1;p->rtag = 1;//都赋值为指针createTree(p->lchild);createTree(p->rchild);
}

接下来是线索二叉树的建立

就以中序序列为例,这里把0作为线索,1作为指针,左线索指向前驱,有线索指向后继也就是ltag和rtag

为了后面的遍历的方便一般会额外建立一个根节点的根节点,也就是所谓头结点,作为遍历序列的前驱和最后一个节点的后继,也就是最先和最后

第一步是进行头结点的初始化,头结点的两个指针域一定是线索,一开始让头结点的右线索指向自己,因为这时候还不知道后继是谁,左线索要视根节点的情况而定,要是根节点为空也就是一棵空树的话,没有人的前驱是头结点,那么头结点的左线索也指向自己。

然后递归建立线索二叉树,这里的pre是全局变量,在初始化的时候pre指向了头结点,传参是根节点,可以看到这里的pre和p(传参)就是前驱和后继的关系,在后面的动态变化中也要一直维护这种关系(这也是为什么一定要以中序去建立线索二叉树),从而能够不断去更新pre节点的右线索(后继)和p的左线索(前驱),当然更新的前提是这个指针域必须为空。

ptr pre;//全局变量用来记录前驱用的,这里实际上一直在变//线索化
void thread(ptr p) {//地址不引用也可以修改内容if (p == NULL)return;//空节点无意义thread(p->lchild);//下面开始线索化,右线索指向后继,左线索指向前驱if (pre->rchild == NULL) {pre->rtag = 0;pre->rchild = p;}if (p->lchild == NULL) {p->ltag = 0;p->lchild = pre;}pre = p;thread(p->rchild);
}//建立线索二叉树
//线索0指针1
void createThread(ptr &pf,ptr pb) {//pfront和pbehind
//分别前驱和当前节点,其实就是头结点和根节点,这里实际上到最后都是一样的pf = (ptr)malloc(Size);pf->ltag = 0;pf->rtag = 0;//线索pf->rchild = pf;//右指针指向自己if (!pb) {pf->lchild = pf;return;}//空树pre = pf;pf->lchild = pb;thread(pb);pre->rtag = 0;pre->rchild = pf;//pf没有变但是pre变了,变成了最后一个节点,这个顺序要注意
}

遍历操作

线索二叉树本身的右线索就已经指向了遍历序列的后继,只要找到了右线索,那么指向的那个节点直接输出就可以,所以首先要根据一定的顺序找到第一个节点,中序的第一个节点就是顺着头结点一直向左下找,找到左孩子为空(有右孩子不影响,根在右之前),那么这个就是第一个节点,这个其实是一组输出,然后根据左根右遍历原则,这时候去看右指针域是不是线索,是的话直接跳转输出,不是的话(可能是有右孩子,这时候tag为指针,或者已经指向头结点了),那么就退出,跳转到那个指针,然后再以相同的规则,一直往左下找找到没有右孩子,再去找一直找到最终指向头结点退出

//其实就是按照规则先去找到最左下的然后通过右线索(直接指向遍历序列的后继),再以同样规则查找
void print(ptr T) {ptr p;p = T->lchild;//开始遍历while (p != T) {while (p->ltag == 1)p = p->lchild;//找到最左的节点printf("%c", p->data);//输出最左的字母while (p->rtag == 0 && p->rchild != T) {//找后继,一直找找到找不到了为止p = p->rchild;printf("%c", p->data);}p = p->rchild;}
}

全部代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>char a[10000];
int index;//用作建树的时候控制数组下表,这里有多组样例,也不知道有什么更好的办法
typedef struct TreeNode* ptr;
#define Size sizeof(TreeNode)
struct TreeNode {char data;int ltag,rtag;//标记是线索还是指针ptr lchild, rchild;//
};//建立二叉树
void createTree(ptr &p) {if (index == strlen(a))return;//建完了index++;char ch = a[index];if (a[index] == '#') {p = NULL;return;}p = (ptr)malloc(Size);p->data = ch; //不要忘记填充数据p->ltag = 1;p->rtag = 1;//都赋值为指针createTree(p->lchild);createTree(p->rchild);
}ptr pre;//全局变量用来记录前驱用的,这里实际上一直在变//线索化
void thread(ptr p) {//地址不引用也可以修改内容if (p == NULL)return;//空节点无意义thread(p->lchild);//下面开始线索化,右线索指向后继,左线索指向前驱if (pre->rchild == NULL) {pre->rtag = 0;pre->rchild = p;}if (p->lchild == NULL) {p->ltag = 0;p->lchild = pre;}pre = p;thread(p->rchild);
}//建立线索二叉树
//线索0指针1
void createThread(ptr &pf,ptr pb) {//分别前驱和当前pf = (ptr)malloc(Size);pf->ltag = 0;pf->rtag = 0;//线索pf->rchild = pf;//右指针指向自己if (!pb) {pf->lchild = pf;return;}//空树pre = pf;pf->lchild = pb;pf->ltag = 0;//线索thread(pb);pre->rtag = 0;pre->rchild = pf;//pf没有变但是pre变了,变成了最后一个节点,这个顺序要注意
}//其实就是按照规则先去找到最左下的然后通过右线索(直接指向遍历序列的后继),再以同样规则查找
void print(ptr T) {ptr p;p = T->lchild;//开始遍历while (p != T) {while (p->ltag == 1)p = p->lchild;//找到最左的节点printf("%c", p->data);//输出最左的字母while (p->rtag == 0 && p->rchild != T) {//找后继,一直找找到找不到了为止p = p->rchild;printf("%c", p->data);}p = p->rchild;}
}void mediumtPrint(ptr p) {if (p == NULL)return;mediumtPrint(p->lchild);printf("%c", p->data);mediumtPrint(p->rchild);
}int main()
{ptr root, rootParent;while (~scanf("%s", a)){index = -1;root = (ptr)malloc(Size);createTree(root);//先建树//mediumtPrint(root);//验证树建立的正确性createThread(rootParent, root);//建立线索二叉树print(rootParent);//中序遍历线索二叉树输出printf("\n");}return 0;
}

线索二叉树的建立和遍历相关推荐

  1. 第10周项目实践 线索二叉树的建立及遍历

    typedef struct node {     Elemtype date;     int ltag,rtag;     struct node lchild;     struct node ...

  2. 线索二叉树,画图教你秒懂线索二叉树(线索二叉树的建立和简单操作)逻辑代码分析

    数据结构专升本学习,线索二叉树 前言 前面我们学习树和二叉树的一些基本操作,今天我们学习一个新的知识,学习一下线索二叉树,线索二叉树是由二叉链存储结构变化而来的(我们先得有个二叉链树,再做处理),就是 ...

  3. 二叉树的建立和遍历算法 - 数据结构和算法47

    二叉树的建立和遍历算法 让编程改变世界 Change the world by program   有童鞋会说,我们上节课研究这么多遍历的方法干啥呢?聪明的鱼油们怎么看?! 对于二叉树,思路方面我们已 ...

  4. 小朋友学数据结构(3):二叉树的建立和遍历

    小朋友学数据结构(3):二叉树的建立和遍历 一.基本概念 BinaryTree.png 二叉树:每个结点的子结点个数不大于2的树,叫做二叉树. 根结点:最顶部的那个结点叫做根结点,根结点是所有子结点的 ...

  5. C语言二叉树实验报告流程图,二叉树的建立与遍历实验报告(c语言编写,附源代码).doc...

    二叉树的建立与遍历实验报告(c语言编写,附源代码).doc 第 1 页,共 9 页二叉树的建立与遍历实验报告级 班 年 月 日 姓名 学号_ 1实验题目建立一棵二叉树,并对其进行遍历(先序.中序.后序 ...

  6. 二叉树的遍历实验报告C语言,二叉树的建立与遍历实验报告(c语言编写,附源代码)...

    程序用VC编写,实现建立一棵二叉树的功能,并对其进行遍历(先序.中序.后序),并且打印输出遍历结果. 二叉树的建立与遍历实验报告 级 班 年 月 日 姓名 学号_ 1.实验题目 建立一棵二叉树,并对其 ...

  7. 数据结构——二叉树的建立与遍历算法(实验报告)

    实验名称:二叉树的建立与遍历算法          指导教师: 实验日期:2022年月日 实验地点: 成绩: 实验目的: 1.掌握二叉树的定义. 2.二叉树的链式存储结构及在链式存储结构中三种遍历(前 ...

  8. 线索二叉树实现中序遍历

    文章目录 前言 一.方法可行性 二.主要代码实现 1.新的树节点定义 2.为中序遍历增加线索 3.中序遍历输出 三.所有代码 前言 如需多次按前中后序遍历二叉树,使用线索二叉树可以加速二叉树的遍历. ...

  9. 二叉树的建立和遍历的各种问题

    链表声明: //基本结构声明 #include<iostream> #include<queue> #include<stack> #include<cstd ...

  10. 二叉树的建立与遍历(先中后层序)

    在做一些算法题时,我会经常用到VS2017去测试,每次去找一个合适的二叉树觉得很麻烦,今天就自己写了一个放在博客上,下次就直接复制了 包含二叉树的建立,以及二叉树的前序遍历.中序遍历.后序遍历和层序遍 ...

最新文章

  1. [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]用户sa 登录 ...
  2. Java前沿分享:value或许成为java的新关键字
  3. 博客会被搬去csdn
  4. pycharm中一直跳出updating indices...indexing
  5. 《京东商业化数据分析师培养计划》
  6. 到另一个文件夹 复制hdfs上的文件_HDFS——如何将文件从HDFS复制到本地
  7. springcloud hystrix入门简介(二)
  8. 本地使用Rfam 12.0+
  9. 点和正方形的关系(信息学奥赛一本通-T1056)
  10. SqlBulkCopy批量数据导入(EF实现)
  11. Linux下的NFS网络文件系统
  12. 仿途牛旅游APP项目开发
  13. pear php有什么用?,php – PEAR和PEAR2有什么区别?
  14. python如何执行代码_在Python中重新运行代码块
  15. MySQL数据库实验
  16. 使用PIL改变图像分辨率
  17. c语言案例六 速算24,参阅:C语言速算24数据结构课程设计最终版
  18. CAP定理和BASE原则
  19. 二叉树的顺序存储及基本操作
  20. 模糊控制——(3)模糊自适应整定PID控制

热门文章

  1. 计算房贷利率月供相关信息(等额本息)
  2. 微软商店安装包_闲着不如折腾,教你现在就尝鲜年底才发售的「微软双屏手机」...
  3. Large-scale Video Classification with Convolutional Neural Networks
  4. 视觉-摄像机3】}摄像机镜头--焦距与视角(选相机和镜头)
  5. QoS配置说明(CBWFQ/LLQ/PQ/CQ/WFQ)
  6. Safari Web Extension 开发(1)
  7. AutoCAD.Net 实现创建wipeout遮罩实体
  8. python藏头诗生成器_藏头诗生成器
  9. 罗伯特扫地机器人电池如何取_再续一年——iRobot Braava 380拖地机器人自己动手更换电池...
  10. 认识计算机拓扑结构图,认识计算机网络拓扑结构