線索二叉樹

線索二叉樹,或者說,對二叉樹線索化,實質上就是遍歷一棵二叉樹,在遍歷的過程中,檢查當前結點的左、右指針域是否爲空。如果爲空,將它們改爲指向前驅結點或後繼結點的線索。

當以二叉鏈表作爲存儲結構時,只能找到左右孩子信息,而不能直接得到結點在任意序列中的前驅和後繼信息,這種信息只有在遍歷的動態過程中才能得到。 解決此問題最簡單的辦法是在每個節點上增加兩個指針域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!\n"); 
        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; 
    } 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章