线索二叉树C/C++

来源:互联网 发布:女生学金融 知乎 编辑:程序博客网 时间:2024/06/11 10:08

线索二叉树C/C++

遍历二叉树就是以一定规则将二叉树中的节点排列成一个线性序列,从而得到二叉树节点的各种遍历序列。其实质就是对一个非线性序列进行线性化操作,使得在这个访问序列中每一个节点(除第一个和最后一个)都有一个直接前驱和直接后继。

n个结点的二叉链表中含有n+1(2n-(n-1)=n+1)个空指针域。利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前趋和后继结点的指针(这种附加的指针称为”线索”)。

因此,修改二叉树结点的定义,加入两个标志域,0为指针,1为线索,重新定义如下:

typedef enum{Link, Thread} PointerTag;//线索存储标志位//Link(0):表示指向左右孩子的指针//Thread(1):表示指向前驱或后继的线索typedef struct BiThrNode{    TElemType data;    struct BiThrNode *lchild, *rchild;    PointerTag ltag, rtag;}BiThrNode;

算法如下:

/*递归中序线索化二叉树*/#include <iostream>#include <malloc.h>using namespace std;#define TElemType chartypedef enum{Link, Thread} PointerTag;//线索存储标志位//Link(0):表示指向左右孩子的指针//Thread(1):表示指向前驱或后继的线索typedef struct BiThrNode{    TElemType data;    struct BiThrNode *lchild, *rchild;    PointerTag ltag, rtag;}BiThrNode;void CreatBiThreadTree(BiThrNode *&T){    char e;    cin>>e;    if(e == '#') T = NULL;    else{        T = (BiThrNode *) malloc (sizeof(BiThrNode));        T->data = e;        T->ltag = T->ltag = Link;        CreatBiThreadTree(T->lchild);        CreatBiThreadTree(T->rchild);    }}void InOrderTraverse(BiThrNode *T){    if(T){        InOrderTraverse(T->lchild);        cout<<T->data;        InOrderTraverse(T->rchild);    }}//中序递归线索化算法void InThreading(BiThrNode *&T,BiThrNode *&pre){    if(T){        InThreading(T->lchild, pre);    //递归左孩子线索化         if(!T->lchild){            T->ltag = Thread;            T->lchild = pre;        }        if(!pre->rchild){            pre->rtag = Thread;            pre->rchild = T;        }        pre = T;        InThreading(T->rchild, pre);    //递归右孩子线索化     }}BiThrNode *InOrderThrTree(BiThrNode *T){    BiThrNode *Thre, *pre;    Thre = (BiThrNode *) malloc (sizeof(BiThrNode));    //创建一个结点,左指针指向二叉树根结点,右结点指向自身    Thre->lchild = T;    Thre->rchild = Thre;    pre = Thre;    InThreading(T, pre);    //中序递归线索化    pre->rtag = Thread;    pre->rchild = Thre;    Thre->rchild = pre;    return Thre;}void InOrderThreading(BiThrNode *Thre){    BiThrNode *p;    p = Thre->lchild;    while(p != Thre){   //指针p指回Thre时,遍历结束        while(p->ltag == Link) p = p->lchild;   //左标志位为指针,则向左走        cout<<p->data;        while(p->rtag == Thread && p->rchild != Thre){  //右标志位为线索,并且右孩子不指回Thre,访问p结点后继一次并输出一次            p = p->rchild;            cout<<p->data;        }        p = p->rchild;  //左孩子为空,右线索为指针,则向右移动一次    }    cout<<endl;}int main(){    BiThrNode *t = NULL;    BiThrNode *thre;    CreatBiThreadTree(t);    cout<<"中序遍历:";    InOrderTraverse(t);    cout<<"\n线索化中序遍历:";    thre = InOrderThrTree(t);    InOrderThreading(thre);    return 0;}
0 0
原创粉丝点击