图解中序遍历线索化二叉树,中序线索二叉树遍历,C\C++描述
body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}
|
对二叉树进行中序遍历后,将所有空指针域中的rchild改为指向它们的后继结点。
① H的后继是D
...
⑥ G的后继是NULL,中序遍历最后一个节点
此时共有6个空指针域被利用
|
将所有空指针域中的lchild改为指向当前节点的前驱。
① H的前驱是NULL,中序遍历的第一个结点
...
⑥ G的前驱是C
此时共有5个空指针被利用
|
| 二叉树输入过程:ABDH##I##EJ###CF##G## | 中序遍历:HDIBJEAFCG |
|
#include<iostream>
using namespace std;
enum TBT{child=0,thread}; //线索二叉树结点的指针是指向孩子还是前驱后继
typedef struct tbt
{
struct tbt* lchild;
enum TBT ltag;
char data;
enum TBT rtag;
struct tbt* rchild;
}TBTreeNode,*pTBTree;
int createThreadedBinaryTree(pTBTree& root);
void inorderThreadingBinaryTree(const pTBTree& root); //中序线索化二叉树
//在中序遍历的同时就线索化二叉树
void inorderThreadedBinaryTreeTraversal(pTBTree root); //中序线索化二叉树遍历
int main()
{
TBTreeNode* root = nullptr;
int ret = createThreadedBinaryTree(root);
{
if(0==ret)
{
inorderThreadingBinaryTree(root);
cout<<endl;
inorderThreadingBinaryTreeTraversal(root);
cout<<endl;
}
}
system("pause");
}
|
int createThreadedBinaryTree(pTBTree& root)
{
char data;
if(cin>>data)
{
if('#'==data)
{
root = nullptr;
return -1;
}
else
{ //用data数据来初始化root结点,然后递归建立左子树和右子树
root = new TBTreeNode(); //创建结点的时候就把结点全部赋值为空
root->data = data;
createThreadedBinaryTree(root->lchild);
createThreadedBinaryTree(root->rchild);
}
}
return 0;
}
static TBTreeNode* pre = nullptr; //定义一个指针指向中序遍历当前访问结点的前一个访问结点
//线索化结点的后继要用到,因为中序遍历顺序:左子树,根结点,右子树
//前驱可以用刚刚访问过的结点直接赋值,后继还没有访问,这时候当前结点就是上一个访问结点pre的后继
//当然,前提条件是pre的右子树为空
//pre初始值为nullptr,因为从根结点开始访问,前一个访问结点就只能是空了
void inorderThreadingBinaryTree(const pTBTree& root)
{
if(nullptr==root)
return ;
/* 参考中序遍历
inorderTraversal(root->lchild);
cout<<root->data<<" ";
inorderTraversal(root->rchild);
*/
inorderThreadingBinaryTree(root->lchild); //中序遍历左子树
//判断结点指针域可不可以线索化
if(nullptr==root->lchild) //如果左子树为空,就可以把指针域拿来线索化,指向前驱
{
root->lchild = pre;
root->ltag = thread;
}
if(nullptr!=pre&&nullptr==pre->rchild) //如果当前访问的根结点不为空,并且前面访问的结点pre右子树为空,线索化前一个结点的后继
{
pre->rchild = root;
pre->rtag = thread;
}
//访问根结点就变成修改前一个访问结点指针pre
pre = root; //之后要访问右子树,当前结点自然就是pre
inorderThreadingBinaryTree(root->rchild); //中序遍历右子树
}
void inorderThreadedBinaryTreeTraversal(pTBTree root)
{
if(nullptr==root)
return;
while(nullptr!=root)
{
while(nullptr!=root->lchild&&child==root->ltag) //两个条件,区别中序遍历第一个结点的前驱是nullptr
{//搜寻从根结点开始的左子树的最后一个节点
root = root->lchild;
}
cout<<root->data<<" "; //输出根结点
while(thread==root->rtag) //该结点有后继,意味着没有右子树
{
cout<<root->rchild->data<<" "; //直接输出后继,也就是中序遍历当前结点下一个要访问的结点的值
root = root->rchild; //根结点回溯到后继
}
//该结点有右子树,root->rtag==child,左子树已经遍历完了,这里进入右子树
root = root->rchild; //重复上面的操作
}
}
|
图解中序遍历线索化二叉树,中序线索二叉树遍历,C\C++描述的更多相关文章
- 图解前序遍历线索化二叉树,前序线索二叉树遍历,C\C++描述
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- YTU 3026: 中序线索化二叉树
原文链接:https://www.dreamwings.cn/ytu3026/2896.html 3026: 中序线索化二叉树 时间限制: 1 Sec 内存限制: 128 MB 提交: 9 解决: ...
- JAVA递归实现线索化二叉树
JAVA递归实现线索化二叉树 基础理论 首先,二叉树递归遍历分为先序遍历.中序遍历和后序遍历. 先序遍历为:根节点+左子树+右子树 中序遍历为:左子树+根节点+右子树 后序遍历为:左子树+右子树+根节 ...
- 线索化二叉树的构建与先序,中序遍历(C++版)
贴出学习C++数据结构线索化二叉树的过程, 方便和我一样的新手进行测试和学习 同时欢迎各位大神纠正. 不同与普通二叉树的地方会用背景色填充 //BinTreeNode_Thr.h enum Point ...
- 后序线索化二叉树(Java版)
前面介绍了前序线索化二叉树.中序线索化二叉树,本文将介绍后序线索化二叉树.之所以用单独的一篇文章来分析后序线索化二叉树,是因为后序线索化二叉树比前序.中序要复杂一些:另外在复习线索化二叉树的过程中,大 ...
- 数据结构与算法---线索化二叉树(Threaded BinaryTree)
先看一个问题 将数列 {1, 3, 6, 8, 10, 14 } 构建成一颗二叉树 问题分析: 当我们对上面的二叉树进行中序遍历时,数列为 {8, 3, 10, 1, 6, 14 } 但是 6, 8 ...
- C#数据结构-线索化二叉树
为什么线索化二叉树? 对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上,否则我们只知道后续的左右子树.现在我们充分利用二叉树左右子树的空节点,分别指向当前节点的前驱.后继,便 ...
- 【算法】二叉树、N叉树先序、中序、后序、BFS、DFS遍历的递归和迭代实现记录(Java版)
本文总结了刷LeetCode过程中,有关树的遍历的相关代码实现,包括了二叉树.N叉树先序.中序.后序.BFS.DFS遍历的递归和迭代实现.这也是解决树的遍历问题的固定套路. 一.二叉树的先序.中序.后 ...
- 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序
接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...
随机推荐
- Java中类似C#中Task.wait()的类CountDownLatch
当主线程开辟多个子线程,而又需要这些子线程都执行完成后再执行主线程后续的操作,在C#中可以通过Task的wait方法来实现,然而在Java中也有类型的类CountDownLatch,具体用法如下: p ...
- 一次dropzone体验
对于前端,本人不是太擅长,对于当前的一些网上的样例,也许是习武悟性太差,不是太透,所以只能通过blog的方式记录下一些武功套路,便于以后查询使用 首先,我们需要知道这个武功适应的战场. 什么是drop ...
- 20165327 2017-2018-2 《Java程序设计》第6周学习总结
20165327 2017-2018-2 <Java程序设计>第6周学习总结 教材内容总结 第八章 String类常用方法 public int length() public boole ...
- Hibernate相关的查询 --Hibernate框架基础
接着上一篇博文:Hibernate第一个程序(最基础的增删改查) --Hibernate本例是对Hibernate查询的扩展,使用HQL语句查询 /** * HQL添加预先需要保存的测试数据 */ @ ...
- 分享基于EF+WCF的通用三层架构及解析
本项目结合EF 4.3及WCF实现了经典三层架构,各层面向接口,WCF实现SOA,Repository封装调用,在此基础上实现了WCFContext,动态服务调用及一个分页的实例. 1. 项目架构图: ...
- Apache Hadoop Operations at Scale
book: Hadoop Operations,A Guide for Developers and Administrators Apache Hadoop Operations at Scale ...
- PHP用PDO
$pdo = new PDO('mysql:host=localhost;dbname=jmyp','root','root'); $pdo->exec('set names utf8'); $ ...
- 诡异的楼梯 HDU - 1180
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向, ...
- 00-自测4. Have Fun with Numbers
Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, wit ...
- sqlite3 查询表
cx = sqlite3.connect("c:/数据库地址") # 打开数据库cu = cx.cursor()# query the tablerows = cu.execute ...