【数据结构】-线索二叉树(后序)
后序线索化二叉树
- 1.头文件及类型定义
- 2.线索二叉树结点类型定义
- 3.函数声明
- 4.基本操作
- 4.1 先序建立线索二叉树
- 4.2 初始化tag
- 4.3 后序线索化二叉树
- 4.3.1 访问并建立线索
- 4.3.2 遍历
- 4.3.3 后序线索化主过程
- 4.4 寻找后序前驱
- 4.5 逆向后序遍历
- 4.5.1 打印结点
- 4.5.2 利用后序前驱实现逆向后序遍历
- 4.6 main函数
- 4.7 测试
- 4.7.1 二叉树结构
- 4.7.2 测试结果
- 5.小结
1.头文件及类型定义
#include<stdio.h>
#include<stdlib.h>
#define ElemType char
2.线索二叉树结点类型定义
//线索二叉树结点类型定义
typedef struct ThreadNode {ElemType data; //数据元素struct ThreadNode* lchild, * rchild; //左、右孩子指针int ltag, rtag; //左、右线索标志//tag=0,表示指针指向孩子;tag=1,表示指针是“线索”,ltag指向前驱,rtag指向后继
}ThreadNode, * ThreadTree;
3.函数声明
/*函数声明*/
void CreateThTree(ThreadTree& T); //1.先序建立线索二叉树
void InitThread(ThreadTree& T); //2.初始化tag
void visit1(ThreadNode* q); //3-1.访问并建立线索
void PostThread(ThreadTree T); //3-2.遍历
void CreatePostThread(ThreadTree T); //3-3.后序线索化主过程
ThreadNode* PreNode(ThreadNode* p); //4.找到p的前驱结点
void visit2(ThreadNode* p); //5-1.打印结点
void RevPostOrder(ThreadNode* T); //5-2.利用后序前驱实现逆向后序遍历
4.基本操作
4.1 先序建立线索二叉树
/*1.先序建立线索二叉树*/
void CreateThTree(ThreadTree& T) {char c;scanf("%c", &c);if (c == '#')T = NULL;else {T = (ThreadNode*)malloc(sizeof(ThreadNode));T->data = c;CreateThTree(T->lchild);CreateThTree(T->rchild);}
}
4.2 初始化tag
/*2.初始化tag*/
void InitThread(ThreadTree& T) {if (T != NULL) {T->ltag = 0;T->rtag = 0; //初始化当前树中的tag指针为0,表示还未线索化InitThread(T->lchild); //递归遍历左子树InitThread(T->rchild); //递归遍历右子树}
}
4.3 后序线索化二叉树
4.3.1 访问并建立线索
ThreadNode* pre = NULL; //pre指向当前访问结点的前驱
//3-1.访问并建立线索
void visit1(ThreadNode* q) {if (q->lchild == NULL) { //左子树为空,建立前驱线索q->lchild = pre;q->ltag = 1;}if (pre != NULL && pre->rchild == NULL) { pre->rchild = q; //建立前驱结点的后继线索pre->rtag = 1;}pre = q; //标记当前结点为刚刚访问过的结点
}
4.3.2 遍历
//3-2.遍历
void PostThread(ThreadTree T) {if (T != NULL) {PostThread(T->lchild); //后序遍历左子树PostThread(T->rchild); //后序遍历右子树visit1(T); //访问根节点}
}
4.3.3 后序线索化主过程
//3-3.主过程
void CreatePostThread(ThreadTree T) {pre = NULL; //pre初始化为NULLif (T != NULL) { //非空二叉树才能线索化 PostThread(T); //后序线索化二叉树if (pre->rchild == NULL) pre->rtag = 1; //处理遍历的最后一个结点}
}
4.4 寻找后序前驱
//4.寻找后序前驱
ThreadNode* PreNode(ThreadNode* p) {if (p->ltag == 0) { //若ltag=0,说明所找结点有左孩子if (p->rtag == 0) //若rtag=0return p->rchild; //说明所找结点有右孩子,根据后序遍历的特点(左-右-根),右孩子为前驱else //若rtag=1return p->lchild; //说明所找结点无右孩子,则前驱结点为其左孩子}elsereturn p->lchild; //若ltag=1,说明所找结点无左孩子,则返回前驱线索
}
4.5 逆向后序遍历
4.5.1 打印结点
//5-1.打印结点
void visit2(ThreadNode* p) {printf("%c\t", p->data);
}
4.5.2 利用后序前驱实现逆向后序遍历
//5-2.利用后序前驱实现逆向后序遍历:空间复杂度为O(1)
void RevPostOrder(ThreadNode* T) {for (ThreadNode* p = T; p != NULL; p = PreNode(p))visit2(p);
}
4.6 main函数
int main() {ThreadTree T;/*1、创建二叉树*/printf("先序创建二叉树:");CreateThTree(T);/*2、初始化tag为0*/InitThread(T);/*3、后序线索化*/CreatePostThread(T);/*4、寻找后序前驱(用根结点测试)*/printf("根结点的后序前驱为:%c\n", PreNode(T)->data);/*6、逆向后序遍历二叉树*/printf("<————逆向后序遍历————>\n");RevPostOrder(T);return 0;
}
4.7 测试
4.7.1 二叉树结构
4.7.2 测试结果
5.小结
- 对于后序线索二叉树并不会出现“转圈"现象,原因是根结点是最后被访问的,不可能再回去访问其左右孩子指向的子树。
- 另外,同先序线索二叉树一样,后序线索二叉树也存在类似的问题:即只能找到后序前驱。具体分析同先序线索二叉树类似,已在上一篇文章小结中介绍,此处不再展开。
【数据结构】-线索二叉树(后序)相关推荐
- c++ stack 遍历_五分钟C语言数据结构 之 二叉树后序遍历(非递归很重要)
五分钟C语言实现常见数据结构 今天的内容分享的是二叉树后序遍历 DP问题,欢迎关注 动态规划一篇就够了 全网最详细, 逐步理解, 万字总结 - Johngo的文章 - 知乎 https://zhuan ...
- (数据结构)二叉树后序遍历
二叉树后序遍历 二叉树后序遍历的实现思想是: 访问当前节点的左子树 访问当前节点的右子树 访问根节点 图 1 二叉树 以上图 1 为例,后序遍历的过程如下: 从根节点 1 开始,遍历该节点的左子树(以 ...
- 线索二叉树 C语言 数据结构 先序线索二叉树 中序线索二叉树 后序线索二叉树
在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序.中序.后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化. 文章目录 一.c语言实现先序线索.中序线 ...
- 线索二叉树(中序、先序和后序及遍历)
链式存储 线索二叉树是二叉树的一类,在看线索二叉树之前我们先看一下二叉树的链式存储. 一个二叉树的存储例子(后面用到的二叉树都是这棵): 代码是这样的: public class BinaryTree ...
- sdut 2137 数据结构实验之求二叉树后序遍历和层次遍历
数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descr ...
- 数据结构实验之求二叉树后序遍历和层次遍历
数据结构实验之求二叉树后序遍历和层次遍历 Description 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历和层序遍历. Input 输入数据有多组,第一行是一个整数t (t<100 ...
- 数据结构之 二叉树---求二叉树后序遍历和层次遍历(先建树,再遍历)
数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历. 输入 输入 ...
- 线索二叉树中序非递归线索化以及递归线索化构建和遍历算法
引文 大部分教材给出了 线索二叉树的中序递归线索化以及中序遍历,但是没给出非递归,现在网上大部分非递归算法代码各种条件判断写的比较离谱,所以干脆自己总结了一个清晰的.线索二叉树中序非递归线索化以及递归 ...
- 后序遍历的非递归算法python_二叉树后序遍历(递归与非递归)算法C语言实现...
二叉树后序遍历的实现思想是:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点元素. 图 1 二叉树 如图 1 中,对此二叉树进行后序遍历的操作过程为: 从根节点 1 ...
最新文章
- 生成keystore是报错拒绝访问(已测试)
- 鸿蒙系统8月7号,主动告别安卓,华为或很快推出搭载鸿蒙系统的手机
- 更改UISwitch大小
- linux之find
- ㉔云上场景:瑞云科技,支持Render cloud的超强计算
- 将Web项目部署到华为云服务器的Linux的Tomcat中
- 豆果美食,把人们带回厨房
- java如何实现定时任务_Java定时任务的三种实现方式
- mysql用创建的用户登陆并修改表格_MySQL 基础学习二:创建一个用户表,并增删改查...
- python从小到大的顺序输出_「小白专栏」Python中使用for循环,为什么输出结果不是按顺序?...
- oracle logfile sync,oracle等待事件3构造一个DirectPathwrite等待事件和构造一个LogFileSync等待事件...
- Android10一直获取IP地址,Android 获取IP地址的实现方法
- No module named sqlite3解决
- 他曾经复读才考上三本,如今让华为开出 201 万年薪(其实还拒绝了 360 万 offer)...
- tongweb自动部署_用apache配置TongWeb集群
- java实现医嘱管理系统_Chis5.0医嘱管理系统业务使用手册
- deepin系统文本编辑器
- 顶顶通软电话介绍-一个网络电话客户端(SIP软电话)
- 鱼塘钓鱼(贪心算法)--算法设计
- Linux下qt程序部署到ARM开发板上: error: Upload of file “你的程序“ failed. The server said: “Failure
热门文章
- CodeMix使用教程:构建管道和验证
- 【深度学习】 NLP和神经网络表示
- 树莓派VNC分辨率,修改无效的解决方案
- Python可迭代对象和迭代器对象详解
- 获取基站LAC CID
- python apriori算法 sklearn_sklearn(九)apriori 关联规则算法,以及FP-growth 算法
- 2023年4月实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】
- android+网络下载资源,【已解决】Android中利用HttpClient等库实现网络文件下载
- Linux下的cut选取命令详解
- HikariPool-1 -Starting...