#include <iostream>
typedef struct TreeNode{
ElemType e;
int ltag, rtag;
TreeNode *lchild, *rchild;
}TreeNode, * BiTree;
void PreThread(BiTree *Tr) {
if (!Tr)
return;
if (pre && !pre->rchild) {
pre->rtag = 1;
pre->rchild = Tr;
}
if (!Tr->lchild) {
Tr->ltag = 1;
Tr->lchild = pre;
}
pre = Tr;
/*
在线索化中,当前节点的指针域有且只有lchild会发生变化.
pre节点先于current node被visit过了,不会造成任何影响.
而且只有前序遍历会导致指针域先于节点的遍历这种情况的发生.
*/
if (!Tr->ltag)
PreThread(Tr->lchild);
PreThread(Tr->rchild);
}
void MidstThread(BiTree *Tr, TreeNode * &pre) {
if (!Tr)
return;
MidstThread(Tr->lchild);
if (pre && !pre->rchild) {
pre->rtag = 1;
pre->rchild = Tr;
}
if (!Tr->lchild) {
Tr->ltag = 1;
Tr->lchild = pre;
}
pre = Tr;
MidstThread(Tr->rchild);
}
void PostThread(BiTree *Tr) {
if (!Tr)
return;
PostThread(Tr->lchild);
PostThread(Tr->rchild);
if (pre && !pre->rchild) {
pre->rtag = 1;
pre->rchild = Tr;
}
if (!Tr->lchild) {
Tr->ltag = 1;
Tr->lchild = pre;
}
Pre = Tr;
}
int Thread(BiTree Tr) {
BiTree pre = NULL;
MidstThread(Tr, pre);
pre->rtag = 0;
pre->rchild = NULL;
}
//中序线索树的一些操作.
int GetLeftMost(BiTree *Tr) {
while (!Tr->ltag && Tr->lchild) {
Tr = Tr->lchild;
}
return Tr;
}
int GetNext(BiTree *Tr) {
if (Tr->rtag)
return Tr->rchild;
return GetLeftMost(Tr->rchild);
}
int GetPrior(BiTree *Tr) {
if (Tr->ltag)
return Tr->lchild;
return GetLeftMost(Tr->lchild);
}
int MidstTraverse(BiTree *Tr) {
for (Tr = GetLeftMost(Tr); Tr; Tr = GetNext(Tr))
visit(Tr);
}
//前序线索树的一些操作. 以下假定其存储结构为三岔链表,声明如下.
typedef struct TreeNode{
ElemType e;
int ltag, rtag;
TreeNode *lchild, *rchild, *parent;
}TreeNode, * BiTree;
//dfs建🌲的时候改一下parent域就好了.
int GetRightMost(BiTree Tr) {
while (1) {
if (!Tr->rtag && Tr->rchild)
Tr = Tr->rchild;
else if(!Tr->ltag && Tr->lchild)
Tr = Tr->lchild;
}
return Tr;
}
int GetNext(BiTree Tr) {
//Case 1: 能直接找到后继
if (Tr->rtag)
return Tr->rchild;
//Case 2: 有左儿子,左儿子就是后继
if (!Tr->ltag && Tr->lchild)
return Tr.lchild;
//Case 3: 只有右儿子,右儿子是后继
if (!Tr->rtag && Tr->rchild)
return Tr->rchild;
//没有右儿子的时候一定能找到前驱;
//有右儿子的两种情况也能找得到.
}
int GetPrior(BiTree Tr) {
//Case 1: ltag
if (Tr->ltag)
return Tr->lchild;
//Case 2: 需要找父节点帮忙
//SubCase 1: 没有父亲,根
if (!Tr->parent)
return false;
//SubCase 2: 我是父节点的左儿子,我的前驱就是父亲.
if (Tr->parent->lchild == Tr) {
return Tr->parent;
}
//SubCase 3: 我是父节点的单独右儿子
if (Tr->parent->lchild == NULL) {
return Tr->parent;
}
//SubCase 4: 有左儿子也有右儿子,我是右儿子.
return GetRightMost(Tr->parent->lchild);
}
//后序的情况也类似,不再赘述. 前序线索树找不到前序、后序线索树找不到后序.
线索化和线索树的遍历
最新推荐文章于 2024-10-05 12:30:18 发布