線索二叉樹

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

typedef char DataType;
typedef enum{Link,Thread}PointerTag;

typedef struct TreeNode{    
    DataType data;
    struct TreeNode *lchild ,*rchild;
    PointerTag ltag,rtag;

}ThreadNode,*ThrTree;


ThrTree pre;

//創建二叉樹
void createT(ThrTree *t){
    char c;
    scanf("%c",&c);
    if(c=='.'){
        *t =NULL;
    }else{  
        *t = (ThreadNode*)malloc(sizeof(ThreadNode));
        (*t)->data = c;

         //初始化左右tag都為Link  0
        (*t)->ltag = Link;  
        (*t)->rtag = Link;
        
        createT(&(*t)->lchild);
        createT(&(*t)->rchild);
    }
}

void visit(DataType d){
    printf("%c",d);
}

/*中序遍歷插入線索*/
void inordertraversalThread(ThrTree *t){
    
    if((*t)){
        inordertraversalThread(&(*t)->lchild);  
        if(!(*t)->lchild){
            (*t)->lchild = pre;
            (*t)->ltag = Thread;
        }
        if(! pre->rchild){
            pre->rtag = Thread;
            pre->rchild=*t;
        }
        pre = *t;  //指向前驅
        inordertraversalThread(&(*t)->rchild);
    }
}


/*中序非遞歸 遍歷線索二叉樹*/
void InOrderTraverse(ThrTree thr){

    ThrTree t;
    t = thr->lchild;//獲取根節點
    //開始遍歷  如果thr==t  等于循環了一圈  就結束遍歷
    while( thr != t )  {
        //這一步操作是為了 讓t走到中序遍歷的第一個元素
        while(t->ltag == Link){
            t = t->lchild;
        }
        //外圈打印當前的元素
        visit(t->data);
        //中序遍歷獲取每個元素  判斷是否有線索的節點  如果有指向下一個并打印數據
        //有兩種情況會退出循環 
        // 1  就是rchild==thr  也就是到中序所有都遍歷完了 
        // 2  t->rtag!=Thread  也就是元素有右節點 沒有線索 退出循環,讓外圈循環打印數據
        while(t->rtag==Thread && t->rchild!=thr){
            t = t->rchild;
            visit(t->data);
        }       
        //指向下一個元素
        t = t->rchild;
    }
}

void main(){
    
    ThrTree t= NULL;
    ThrTree thr = (ThreadNode*)malloc(sizeof(ThreadNode));  //線索指針
    
    createT(&t);  //前序創建二叉樹
    
    //初始化線索指針
    thr->ltag=Link;    
    thr->rtag = Thread;
    thr->rchild = thr;  //左子數先指向自己 
    
    if(!t){     
        thr->lchild = thr;   //如果數創建失敗 還是指向自己
    }else{
        thr->lchild = t;    // 指向根節點
        thr->ltag = Link; 
        pre = thr; //初始化指向頭指針  也就是單獨的線索指針 
        inordertraversalThread(&t); 

        //中序最后一個元素指向線索指針
        pre->rchild = thr;  
        pre->rtag = Thread;  
        thr->rchild = pre;   //線索指針回指中序最后一個節點
    }
        
    InOrderTraverse(thr);
    printf("\n");
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容