- 线索二叉树的搭建和遍历(c++版)
动画版 https://www.bilibili.com/video/BV1MP4y1i7mK/
#include <iostream>
using namespace std;
#define TRUE 1
#define FALSE 0
class ClueBinaryTree
{
private:
typedef struct node
{
char data; // 数据域
node* lchild, * rchild; // 左孩子、右孩子
bool ltag, rtag; // 左标识、右标识(0代表指向左右孩子,1代表指向前驱后继)
}BNode, * BTree;
string str; // 输入的字符串
int sub; // 字符串下标
BTree Root; // 根节点
BTree Head; // 头节点
BTree Last; // 始终指向刚刚访问过的节点
public:
ClueBinaryTree()
{
this->str = "ABD E CF G ";
this->sub = 0;
this->Root = NULL;
this->Head = NULL;
this->createTree(this->Root); // 初始化二叉树
this->InOrderThreading(this->Head, this->Root); // 中序遍历线索化
this->InOrderTraverse(this->Head); // 中序遍历输出二叉树
}
// 初始化二叉树
void createTree(BTree& elem)
{
char c = this->str[this->sub++];
if (' ' == c)
{
elem = NULL;
}
else
{
elem = new BNode;
elem->data = c;
elem->ltag = FALSE;
elem->rtag = FALSE;
this->createTree(elem->lchild);
this->createTree(elem->rchild);
}
}
// 二叉树中序遍历线索化
void InThreading(BTree& T)
{
if (T)
{
this->InThreading(T->lchild); // 递归左孩子线索化
// 节点处理
// ------------------------------------------------------------------------------
if (!T->lchild) // 如果当前节点没有左孩子,左指针指向前驱(即上一个节点)
{
T->ltag = TRUE;
T->lchild = this->Last;
}
if (!this->Last->rchild) // 如果当前节点的上一个节点没有右孩子,右指针指向后继(即当前节点)
{
this->Last->rtag = TRUE;
this->Last->rchild = T;
}
this->Last = T; // 当前节点变成上一个节点,然后继续
// ------------------------------------------------------------------------------
this->InThreading(T->rchild); // 递归右孩子线索化
}
}
// 构建头节点(头节点,根节点)
void InOrderThreading(BTree& Head, BTree& Root)
{
Head = new BNode; // 创建头节点
Head->ltag = FALSE; // 设置左标识(左指针指向左孩子)
Head->rtag = TRUE; // 设置右标识(右指针指向后继)
Head->rchild = Head; // 后继为自身
if (!Root) // 如果为空树,左孩子为自身
{
Head->lchild = Head;
}
else // 不为空树
{
Head->lchild = Root; // 头节点左孩子为根节点
this->Last = Head; // “上一个节点”最初形态
this->InThreading(Root); // 开始线索化
this->Last->rchild = Head; // “上一个节点”的右孩子为头结点
this->Last->rtag = TRUE; // “上一个节点”的右标识为指向后继
Head->rchild = this->Last; // 头节点的后继为“上一个节点”
}
}
// 中序遍历二叉树,非递归
void InOrderTraverse(BTree& Head)
{
BTree p;
p = Head->lchild;
cout << "中序遍历:";
while (p != Head)
{
while (p->ltag == FALSE)
{
p = p->lchild;
}
cout << p->data << " ";
while (p->rtag == TRUE && p->rchild != this->Head)
{
p = p->rchild;
cout << p->data << " ";
}
p = p->rchild;
}
cout << endl;
}
};
int main()
{
ClueBinaryTree c;
system("pause");
return 0;
}