概念
线索二叉树:按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列。在改序列中,除第一个结点外每个结点有且仅有一个直接前驱结点;除最后一个结点外每一个结点有且仅有一个直接后继结点。这些指向直接前驱结点和指向直接后续结点的指针被称为线索(Thread),加了线索的二叉树称为线索二叉树。
百科解释:链接
完整C++代码:
#include <iostream>
using namespace std;
//线索二叉树的链式储存结构
typedef struct BiThrNode
{
char ch; // 数据
struct BiThrNode *lChild, *rChild; // 左右子树
bool LTag, RTag; //左右线索标志
}BiThrNode, *BiThrTree;
BiThrTree pre; // 前驱节点,用来生成线索二叉树
/*
* 创建一个二叉树节点
* 返回创建的新节点
*/
BiThrTree CreateBiThrNode(char ch)
{
BiThrTree newT = new BiThrNode;
newT->ch = ch;
newT->lChild = newT->rChild = NULL;
newT->LTag = newT->RTag = false;
return newT;
}
/*
* 创建二叉树
* 根据输入先序创建二叉树, 输入 # 表示为空树
*/
void CreateBiThrTree(BiThrTree &rootT)
{
char ch;
cin >> ch;
if('#' == ch){
rootT = NULL;
}
else{
rootT = CreateBiThrNode(ch);
CreateBiThrTree(rootT->lChild);
CreateBiThrTree(rootT->rChild);
}
}
/*
* 二叉树的中序线索化
* 中序遍历依次改写指针
*/
void InThreading(BiThrTree rootT)
{
if(rootT){
InThreading(rootT->lChild); //线索化左子树
// 改写左线索指针
if(rootT->lChild == NULL){
rootT->LTag = true;
rootT->lChild = pre;
}else{
rootT->LTag = false;
}
// 改写右线索指针
if(pre->rChild == NULL){
pre->RTag = true;
pre->rChild = rootT;
}else{
pre->RTag = false;
}
pre = rootT; // 记录前驱节点
InThreading(rootT->rChild); // 线索化右子树
}
}
/*
* 二叉树的中序线索化
* 返回头节点
*/
BiThrTree InOrderThreading(BiThrTree rootT)
{
BiThrTree firstT = CreateBiThrNode('#');
firstT->LTag = false;
firstT->RTag = true;
if(rootT == NULL){
firstT->rChild = firstT; // 树为空,则右线索指向自己
}else{
firstT->lChild = rootT; // 左线索指向树根节点
pre = firstT;
InThreading(rootT);
// 最后节点的右线索指针指向头节点
pre->rChild = firstT;
pre->RTag = true;
firstT->rChild = pre; // 右线索指向最后访问的节点
}
return firstT;
}
/*
* 中序遍历线索二叉树
* 重复:输出节点数据,获取后继节点
*/
void InOder_Traverse_Thr(BiThrTree firstT)
{
BiThrTree pT = firstT->lChild; //获取根节点
while(pT != firstT){
// 沿左孩向子下
while(! pT->LTag){
pT = pT->lChild;
}
cout << pT->ch << " ";
// 沿右线索访问后继节点
while(pT->RTag && pT->rChild != firstT){
pT = pT->rChild;
cout << pT->ch << " ";
}
pT = pT->rChild; // 转向右子树
}
}
int main()
{
BiThrTree rootT;
CreateBiThrTree(rootT);
BiThrTree firstT = InOrderThreading(rootT);
InOder_Traverse_Thr(firstT);
return 0;
}
销毁的操作没有写,但对于这个程序,这点内存泄露也没什么影响(^_^)
这里只给出了中序线索化及遍历方法,其它的就不写了(^_^)
参考博文:http://blog.csdn.net/jiajiayouba/article/details/9224403