线索二叉树的概念就不赘述了,最核心的定义就是:结构体中左右标志位的选取,本文中以ltag表示左节点,当ltag为false时,放置左孩子,true时放置前驱节点指针,同理,以rtag表示右节点,当rtag为false时,放置右孩子,true时放置后继节点指针。
以下代码中有详细注释~👧(不过线索二叉树真的好难懂鸭)
typedef struct BiTreeNode
{
char data;
BiTreeNode *lchild;
BiTreeNode *rchild;
bool ltag = false;//指定0为孩子 1为前驱后继
bool rtag = false;//首先指定为0
}*BiClueTree;//起别名 等价于BiClueTree p1=BiTreeNode *p2
BiClueTree Previous;
void CreateBiClueTree(BiClueTree *t)
{
//相当于传地址的操作,可以改变t
//(*t)是一个BiTreeNode型指针
char c;
scanf_s("%c", &c, 1);
if ('#'==c)
{
*t = NULL;
return;
}
(*t) = new BiTreeNode();
(*t)->data = c;
CreateBiClueTree(&((*t)->lchild));
//(*t)->lchild是一个BiTreeNode型指针,也就相当于BiClueTree变量,那么需要进行取地址操作才能进行递归
CreateBiClueTree(&((*t)->rchild));
}
void Clueing(BiClueTree t)
{
if (t)//树不为空
{
Clueing(t->lchild);//一直递归左子树 直到这个t节点属于叶子节点
if (!t->lchild)
{
t->lchild = Previous;//最第一次进来的时候 也就是最左子树的叶子节点 指向头节点的左边
t->ltag = true;
}
if (!Previous->rchild)
{
Previous->rchild = t;
Previous->ltag = true;
}
Previous = t;
Clueing(t->rchild);//这块还没怎们搞懂为啥要递归右孩子
}
}
void ClueTheTree(BiClueTree *head, BiClueTree t)
{
(*head) = new BiTreeNode();
(*head)->rchild = (*head);
(*head)->rtag = false;//刚开始创建的时候右孩子指向自己
if (t==NULL)
{
(*head)->lchild = (*head);
(*head)->ltag = false;//树为空时左孩子还是指向自己
}
else
{
Previous = (*head);
(*head)->lchild = t;
(*head)->ltag = false;//此时左孩子是树的节点啦啦啦啦啦~
Clueing(t);
Previous->rchild = (*head);//最后一个节点 指回头节点
Previous->rtag = true;
(*head)->rchild = Previous;//双向指 和上面一样
}
}
void ShowTheTree(BiClueTree head)
{
BiClueTree p;
p = head->lchild;//指向了根节点
while (p!= head)//没有走到最左子树的叶子节点时
{
while (p->ltag==false)
{
p = p->lchild;
}//结束循环时,找到了那个最左边的根节点
cout << p->data;
while (p->rchild != head && p->rtag==false)
{
//如果这个节点不是最右子树的节点 并且他有右孩子
p = p->rchild;
cout << p->data;
}
//如果不满足上述条件
//那么就是①到了最右子树,现在的p是头节点
//②p是相对靠右的叶子节点,此时 也应该将p给到他的后继 再让大循环判断其是不是头节点
//如果是 退出循环 如果不是 因为最右叶子节点没有左孩子,所以输出本身的数据,再进入其【后继】节点
p = p->rchild;
}
cout << endl;
}
void test20()
{
BiClueTree tree;
BiClueTree head;
CreateBiClueTree(&tree);
ClueTheTree(&head, tree);
ShowTheTree(head);
}
int main()
{
cout << "正在测试我的代码。。" << endl;
srand((unsigned int)time(NULL));
test20();
system("pause");
}
以下是效果图🎠
emmm 略显粗糙 。。。第一行是用户输入的前序二叉树,第二行是程序给出的中序遍历结果,emmm,凑合看也还Key拉~✨ 如果明天不懒 就来补图!giao