对下图的二叉树进行
1.创建一个带线索域的二叉树,数据类型如下:`typedef struct
当 tag 为0时,代表child 正常指向下一个节点
当tag为1时,child为线索,其中
- lchild 为指向中序遍历前驱
- rchild 为指向中序遍历后缀
BiThrNode {
Telemltype data;
struct BiThrNode* lchild, * rchild;
int Ltag; // 0 lchild
// 1 prenode
int Rtag; // 0 rchild;
// 1 nextnode
}BiThrNode ,*BiThrTree;
2.创建树(左右线索默认0
BiThrTree Bitree_thread_Create(BiThrTree bt)
{
if (!(node1 = (BiThrTree)malloc(sizeof(BiThrNode)))) return NULL;
if (!(node2 = (BiThrTree)malloc(sizeof(BiThrNode)))) return NULL;
if (!(node3 = (BiThrTree)malloc(sizeof(BiThrNode)))) return NULL;
if (!(node4 = (BiThrTree)malloc(sizeof(BiThrNode)))) return NULL;
if (!(node5 = (BiThrTree)malloc(sizeof(BiThrNode)))) return NULL;
if (!(node6 = (BiThrTree)malloc(sizeof(BiThrNode)))) return NULL;
if (!(node7 = (BiThrTree)malloc(sizeof(BiThrNode)))) return NULL;
node1->Ltag = 0;
bt->lchild = node1;
node1->data = 1;
node1->lchild = node2;
node1->rchild = node3;
node2->data = 2;
node3->data = 3;
node2->lchild = node4;
node2->rchild = node5;
node5->lchild = node6;
node5->rchild = node7;
node4->data = 4;
node5->data = 5;
node6->data = 6;
node7->data = 7;
node4->lchild = node4->rchild = NULL;
node6->lchild = node6->rchild = NULL;
node7->lchild = node7->rchild = NULL;
node3->lchild = node3->rchild = NULL;
node7->Ltag = node1->Rtag = 0;
node6->Ltag = node2->Rtag = 0;
node5->Ltag = node3->Rtag = 0;
node4->Ltag = node4->Rtag = 0;
node3->Ltag = node5->Rtag = 0;
node2->Ltag = node6->Rtag = 0;
node1->Ltag = node7->Rtag = 0;
return bt;
}
3.创建一个递归中序遍历函数
BiThrTree In_order_THreading(BiThrTree bt)
{
bt->Ltag = 0;
bt->Rtag = 1;
pre = bt;
bt->rchild= bt;
if(bt->lchild)
inthread(bt->lchild);
pre->rchild = bt;
pre->Rtag = 1;
bt->rchild = pre;
return bt;
}
void inthread(BiThrTree p)
{
if (p)
{
inthread(p->lchild); //递归
if (!p->lchild)
{
p->Ltag = 1;
p->lchild = pre;
}
if (!pre->rchild)
{
pre->rchild = p;
pre->Rtag = 1;
}
pre = p;
inthread(p->rchild);
}
} /*递归结束后还有bt->rchild ,pre->rchild未配置*/
上图的树中序遍历为 4 5 6 5 7 1 3,
带头节点后为 bt 4 2 6 5 7 1 3
遍历后可以得到一个指针,如下:
4.遍历
void look_thread_tree(BiThrTree bt)
{
BiThrTree p=bt->lchild;
while (p != bt)
{
while (p->Ltag == 0)
p = p->lchild;
visit_thread(p);
while (p->Rtag == 1 && p->rchild != bt)
{
p = p->rchild;
visit_thread(p);
}
p = p->rchild;
}
}
int visit_thread(BiThrTree p)
{
if (p)
{
printf("<<%d>>\n", p->data);
return 1;
}
else
return 0;
}
线索化的目的:
降低常数因子开销和堆栈开销