标签:c++
通过考察各种二叉链表,不管儿叉树的形态如何,空链域的个数总是多过非空链域的个数。准确的说,n各结点的二叉链表共有2n个链域,非空链域为n-1个,但其中的空链域却有n+1个。如下图所示。
因此,提出了一种方法,利用原来的空链域存放指针,指向树中其他结点。这种指针称为线索。
记ptr指向二叉链表中的一个结点,以下是建立线索的规则:
(1)如果ptr->lchild为空,则存放指向中序遍历序列中该结点的前驱结点。这个结点称为ptr的中序前驱;
(2)如果ptr->rchild为空,则存放指向中序遍历序列中该结点的后继结点。这个结点称为ptr的中序后继;
显然,在决定lchild是指向左孩子还是前驱,rchild是指向右孩子还是后继,需要一个区分标志的。因此,我们在每个结点再增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量。结点结构如下所示。
其中:
(1)ltag为0时指向该结点的左孩子,为1时指向该结点的前驱;
(2)rtag为0时指向该结点的右孩子,为1时指向该结点的后继;
(3)因此对于上图的二叉链表图可以修改为下图的养子。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; typedef struct Binode { char data; struct Binode *lchild,*rchild; int ltag,rtag; } Binode,*Bitree; Bitree pre; void CreatTREE(Bitree &T) { char ch; scanf("%c",&ch); if(ch==' ') { T=NULL; } else { T=(Bitree)malloc(sizeof(Binode)); T->data=ch; T->ltag=0; T->rtag=0; CreatTREE(T->lchild); CreatTREE(T->rchild); } return; } void travel_threadtree(Bitree H) //中序遍历线索树 从头节点开始 { Bitree p; p=H->lchild; //p为二叉树头节点 while(p!=H) { while(p->ltag==0) //有左子树 则 一直往下 p=p->lchild; printf("%c ",p->data); while(p->rtag==1&&p->rchild!=H) //根据它的线索一直往后输出 { p=p->rchild; printf("%c ",p->data); } p=p->rchild; //当没有线索时 表示有右子树 } return; } void thread(Bitree T) //线索化 { if(T) { thread(T->lchild); if(!T->lchild) { T->ltag=1; T->lchild=pre; } if(!pre->rchild) { pre->rtag=1; pre->rchild=T; } pre=T; //顺序是左子树 节点 右子树的中序遍历 所有 放这里 thread(T->rchild); } return; } void threading_(Bitree &H,Bitree T) //新增头节点 { H=(Bitree)malloc(sizeof(Binode)); H->rchild=H; H->rtag=0; if(!T) //二叉树为空 { H->lchild=H; H->ltag=0; } else { pre=H; H->lchild=T; H->ltag=0; thread(T); H->rtag=1; H->rchild=pre; // pre->rchild=H; // 构成循环 以备跳出 } return; } int main() { Bitree T,H; CreatTREE(T); threading_(H,T); travel_threadtree(H); return 0; }
标签:c++
原文地址:http://blog.csdn.net/axuan_k/article/details/41173533