线索二叉树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线索二叉树相关的知识,希望对你有一定的参考价值。

线索二叉树,或者说,对二叉树线索化,实质上就是遍历一棵二叉树,在遍历的过程中,检查当前结点的左、右指针域是否为空。如果为空,将它们改为指向前驱结点或后继结点的线索。

当以二叉链表作为存储结构时,只能找到左右孩子信息,而不能直接得到结点在任意序列中的前驱和后继信息,这种信息只有在遍历的动态过程中才能得到。 解决此问题最简单的办法是在每个节点上增加两个指针域fwd和bkwd,分别指示结点依任意次序遍历时得到前驱和后继信息。显然这样做使得结构的存储密度 大大降低,另一方面,在有n个结点的二叉链表中必定存在n+1个空链域。由此设想能否利用这些空链域来存放前驱和后继信息。

试做如下规定:若结点有左子树,则其lchild域指向其左孩子,否则域指示其前驱,若结点有右子树,则其rchild域指示其右孩子,否则令rchild指示其后继。为了避免混淆,尚需改变结点结构,增加两个标志域。
lchild LTag data RTag rchild
其中:

LTag=0  lchild域指示结点的左孩子
LTag=1  lchild域指示结点的前驱
RTag=0  rchild域指示结点的右孩子
RTag=1  rchild域指示结点的后继

以这种结点结构构成的二叉链表作为二叉树的存储结构,叫做线索链表,其中指向结点前驱和后继的指针,叫做线索。加上线索的二叉树称为线索二叉树。对二叉树进行某种次序遍历使其变为线索二叉树的过程叫做线索化。

头文件:

/***************************************************************************************************** 
 *Copyright: Yue Workstation 
 * 
 *FileName: IndexTree.h 
 * 
 *Function: 线索二叉树数据结构定义 
 * 
 *Author: Abel Lee 
 * 
 *CreateOn: 2012-2-19 
 * 
 *Log: 2012-2-19 由Abel Lee创建 
 *****************************************************************************************************/ 

#ifndef INDEX_TREE_H 
#define INDEX_TREE_H 

#include "global.h" 

typedef enum{Link,Thread} PointerTag;     //指针标志 
typedef int DataType; 
typedef struct BiThreTree 
{               //定义结点元素 
    PointerTag LTag,RTag; 
    DataType data; 
    struct BiThreTree *lchild,*rchild; 
}BiThreTree; 

BiThreTree *pre;                     //全局变量,用于二叉树的线索化 

BiThreTree *CreateTree(void); 
void InThread(BiThreTree *T); 
BiThreTree *InOrderThrTree(BiThreTree *T); 
void InThrTravel(BiThreTree *Thre); 

#endif

源文件:

/***************************************************************************************************** 
 *Copyright:Yue Workstation 
 * 
 *FileName: IndexTree.c 
 * 
 *Function: 线索二叉树操作 
 * 
 *Author:Abel Lee 
 * 
 *CreateOn:2012-2-19 
 * 
 *Log:2011-5-3 由Abel Lee创建 
 *****************************************************************************************************/ 

#include "../inc/IndexTree.h" 

/**************************************************************************************************** 
 *Function Name: CreateTree 
 * 
 *Function: 按先序输入建立二叉树 
 * 
 *Parameter:   无 
 * 
 *Return Value:成功返回树的指针,失败返回NULL 
 * 
 *Author:Abel Lee 
 * 
 *Log:2012-2-19 
 ***************************************************************************************************/ 
BiThreTree *CreateTree(void) 
{ 
    BiThreTree *T; 
    DataType e; 
    scanf("%d",&e); 
    if(e==0) 
    { 
        T=NULL; 
    } 
    else 
    { 
        T=(BiThreTree *)malloc(sizeof(BiThreTree)); 
        T->data=e; 
        T->LTag=Link;          //初始化时指针标志均为Link 
        T->RTag=Link; 
        T->lchild=CreateTree(); 
        T->rchild=CreateTree(); 
    } 
    return T; 
} 

/**************************************************************************************************** 
 *Function Name: InThread 
 * 
 *Function: 
 * 
 *Parameter:   无 
 * 
 *Return Value:成功返回树的指针,失败返回NULL 
 * 
 *Author:Abel Lee 
 * 
 *Log:2012-2-19 
 ***************************************************************************************************/ 
void InThread(BiThreTree *T) 
{ 
    BiThreTree *p; 
    p=T; 

    if(p) 
    { 
        InThread(p->lchild); 
        if(!p->lchild) 
        { 
            p->LTag=Thread; 
            p->lchild=pre; 
        } 
        if(!pre->rchild) 
        { 
            pre->RTag=Thread; 
            pre->rchild=p; 
        } 
        pre=p; 
        InThread(p->rchild); 
    } 
} 

/**************************************************************************************************** 
 *Function Name: InOrderThrTree 
 * 
 *Function: 中序线索化二叉树 
 * 
 *Parameter:   T:二叉树指针 
 * 
 *Return Value:成功返回树的指针,失败返回NULL 
 * 
 *Author:Abel Lee 
 * 
 *Log:2012-2-19 
 ***************************************************************************************************/ 
BiThreTree *InOrderThrTree(BiThreTree *T) 
{ 
    BiThreTree *Thre;                  //Thre为头结点的指针 

    Thre=(BiThreTree *)malloc(sizeof(BiThreTree)); 
    if(Thre == NULL) 
    { 
        perror("Thre == NULL,malloc error!
"); 
        return NULL; 
    } 
    Thre->lchild=T; 
    Thre->rchild=Thre; 
    pre=Thre; 
    InThread(T); 
    pre->RTag=Thread; 
    pre->rchild=Thre; 
    Thre->rchild=pre; 
    return Thre; 
} 

/**************************************************************************************************** 
 *Function Name: InThrTravel 
 * 
 *Function: 中序遍历二叉树 
 * 
 *Parameter:   Thre:二叉树指针 
 * 
 *Return Value:成功返回树的指针,失败返回NULL 
 * 
 *Author:Abel Lee 
 * 
 *Log:2012-2-19 
 ***************************************************************************************************/ 
void InThrTravel(BiThreTree *Thre) 
{ 
    BiThreTree *p; 

    p=Thre->lchild; 
    while(p!=Thre)                  //指针回指向头结点时结束 
    { 
        while(p->LTag==Link) 
          p=p->lchild; 
        printf("%4d",p->data); 
        while(p->RTag==Thread&&p->rchild!=Thre) 
        { 
            p=p->rchild; 
            printf("%4d",p->data); 
        } 
        p=p->rchild; 
    } 
}

以上是关于线索二叉树的主要内容,如果未能解决你的问题,请参考以下文章

java实现线索化二叉树的前序中序后续的遍历(完整代码)

C#数据结构-线索化二叉树

线索二叉树

线索化二叉树

线索二叉树

线索二叉树