博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【数据结构周周练】018 利用递归算法及中序遍历将二叉树线索化并遍历
阅读量:4076 次
发布时间:2019-05-25

本文共 3530 字,大约阅读时间需要 11 分钟。

 一、线索二叉树

从今天起,就给大家分享大家期待已久的线索二叉树的代码啦,首先给大家简单讲解一下线索二叉树的概念。

我们通过链式创建的有N个结点的二叉树会产生N + 1个空指针。怎么出现的这N + 1个空指针呢?

重点1:为什么有N个结点的二叉树会产生N + 1个空指针?

我们都知道,每个二叉树的结点都有两个指针,分别指向左孩子和右孩子。在结点初始化过程中设为空,这样就有2 × N个指针,从另一个角度看,除了根节点,每个结点都有唯一的双亲结点,即有N - 1个结点非空,所以剩下N + 1 个空结点。

我们希望能利用这N + 1个空结点,不让其白白浪费,所以通过建立前驱与后继,加快树的访问速度,从而引入线索二叉树。

重点2:线索二叉树构造原则

在二叉树线索化过程中,如果没有左子树,lChild 指向前驱结点,如果没有右子树,rChild 指向前驱结点。同时增加两个标志域表明当前所指对象是指左右子结点还是直接前驱与后继。

标志域含义

 

typedef struct ThreadNode {	int data;               //data field	struct ThreadNode *lChild, *rChild; // left child point and right child point	int ltag, rtag;         //tag of left thread and rignt thread}ThreadNode,*ThreadTree;

 给大家举个例子,如下图,我们以中序为例,D结点左右子结点为空,所以左子结点指向其前驱,后子结点指向其后继。对于B(首结点),没有前驱,指向空;对于A,左右子结点都不为空,则指向左右子结点即可。

二叉树线索化图例

二、示例

利用递归算法及中序遍历将下图的树线索化,先序遍历访问每个结点的编号,数据及所有的孩子结点,并用中序遍历线索化后的二叉树。其中圆角矩形内为结点数据,旁边数字为结点编号,箭头指向的结点为箭尾的孩子结点。

森林转化为二叉树

 

 三、代码

#include
#include
using namespace std;typedef struct ThreadNode { int data; //data field int number; struct ThreadNode *lChild, *rChild; // left child point and right child point int ltag, rtag; //tag of left thread and rignt thread}ThreadNode,*ThreadTree;int number = 0;int yon = 0;int yesOrNo[] = { 1,1,0,1,1,0,0,0,1,0,0,1,1,0,1,1,0,0,0,1,1,0,0,1,0,0 };int numData[] = { 1,2,4,5,6,3,7,8,9,10,11,12,13 };//Operation the node to creat the binary treeint OperationNode(ThreadTree &T) { T = (ThreadTree)malloc(sizeof(ThreadNode)); if (!T) { cout << "空间分配失败(Allocate space failure.)" << endl; exit(OVERFLOW); } //T->ltag = 0; //T->rtag = 0; T->data = numData[number]; T->number = number; number++; T->lChild = NULL; T->rChild = NULL; return 1;}//Eatablish the binary tree void EstablishTree(ThreadTree &T) { OperationNode(T); if (yesOrNo[yon++]) EstablishTree(T->lChild); if (yesOrNo[yon++]) EstablishTree(T->rChild);}void VisitBiTree(ThreadTree &T) { cout << "【" << T->number + 1 << "】The number of present node is :" << T->number << "; "; cout << "\tdata is :" << T->data << "; "; if (T->lChild) { T->ltag = 0; cout << "\n\tlChild's number is :" << T->lChild->number << ","; } else T->ltag = 1; if (T->rChild) { T->rtag = 0; cout << "\n\trChild's number is :" << T->rChild->number << ";"; } else T->rtag = 1; cout << endl;}void PreOrderVisitTree(ThreadTree T) { VisitBiTree(T); if (T->lChild) PreOrderVisitTree(T->lChild); if (T->rChild) PreOrderVisitTree(T->rChild);}//Threaded binary tree by inorder traversal void InThreadTree(ThreadTree &T, ThreadTree &pre) { if (T) { InThreadTree(T->lChild, pre); if (!T->lChild) T->lChild = pre; if (pre && !pre->rChild) pre->rChild = T; pre = T; InThreadTree(T->rChild, pre); }}//Creat the thread binary treevoid CreatInThreadTree(ThreadTree &T) { ThreadTree pre = NULL; if (T) { InThreadTree(T, pre); pre->rChild = NULL; }}ThreadTree FirstNode(ThreadTree T) { while (!T->ltag) T = T->lChild; return T;}ThreadTree NextNode(ThreadTree T) { if (T->rtag == 0) return FirstNode(T->rChild); else return T->rChild;}void VisitThreadTree(ThreadTree T) { cout << "The number of present node is :" << T->number << "; "; cout << "\tdata is :" << T->data << "; \n";}void InOrder(ThreadTree T) { for (ThreadTree p = FirstNode(T); p != NULL; p = NextNode(p)) VisitThreadTree(p);}void main() { ThreadTree T; EstablishTree(T); cout << "\n********【线索化之前遍历二叉树。Traverse binary tree before thread】********" << endl; PreOrderVisitTree(T); cout << "\n********【线索化之后遍历二叉树。Traverse binary tree after thread】********" << endl; CreatInThreadTree(T); InOrder(T);}

四、实现效果

转载地址:http://vdyni.baihongyu.com/

你可能感兴趣的文章
大数据学习:Spark RDD操作入门
查看>>
大数据框架:Spark 生态实时流计算
查看>>
大数据入门:Hive和Hbase区别对比
查看>>
大数据入门:ZooKeeper工作原理
查看>>
大数据入门:Zookeeper结构体系
查看>>
大数据入门:Spark RDD基础概念
查看>>
大数据入门:SparkCore开发调优原则
查看>>
大数据入门:Java和Scala编程对比
查看>>
大数据入门:Scala函数式编程
查看>>
【数据结构周周练】002顺序表与链表
查看>>
C++报错:C4700:使用了非初始化的局部变量
查看>>
【数据结构周周练】003顺序栈与链栈
查看>>
C++类、结构体、函数、变量等命名规则详解
查看>>
C++ goto语句详解
查看>>
【数据结构周周练】008 二叉树的链式创建及测试
查看>>
《软件体系结构》 第九章 软件体系结构评估
查看>>
《软件体系结构》 第十章 软件产品线体系结构
查看>>
《软件过程管理》 第六章 软件过程的项目管理
查看>>
《软件过程管理》 第九章 软件过程的评估和改进
查看>>
分治法 动态规划法 贪心法 回溯法 小结
查看>>