線索二叉樹詳解以及程式碼實現
阿新 • • 發佈:2018-12-25
參照《大話資料結構》188到194頁。
一、二叉樹的線索儲存結構定義
/* 二叉樹線索儲存結構定義 Link = 0,代表指向左右孩子的指標 Thread= 1 代表指向前驅或後繼的線索*/ typedef enum{ Link, Thread} PointerTag; typedef char TypeData; typedef struct BiTreeNode { TypeData data; struct BiTreeNode *lchild, *rchild; PointerTag LTag; PointerTag RTag; }BITREENODE;
二、對二叉樹進行中序遍歷,並把所有的空的左孩子指標指向該節點的前驅,空的右孩子指標指向該節點的後繼。
三、程式碼實現(慢慢去看)
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; /* 二叉樹線索儲存結構定義 Link = 0,代表指向左右孩子的指標 Thread= 1 代表指向前驅或後繼的線索*/ typedef enum{ Link, Thread} PointerTag; typedef char TypeData; typedef struct BiTreeNode { TypeData data; struct BiTreeNode *lchild, *rchild; PointerTag LTag; PointerTag RTag; }BITREENODE; BITREENODE* createBiTree(); /* 建立二叉樹 */ void preOrderBiTree(BITREENODE* T); /* 前序遍歷該二叉樹 */ void InThreadBiTree(BITREENODE* T); /* 中序遍歷線索化該二叉樹 */ void InOrderBiTree_Thread(BITREENODE* T); /* 中序遍歷該線索二叉樹 */ /* 建立二叉樹 */ BITREENODE* createBiTree() { TypeData ch = 0; BITREENODE* pNewNode = NULL; cin >> ch; if(ch == '#') { pNewNode = NULL; } else { /* 給節點分配記憶體 */ pNewNode = (BITREENODE*)malloc(sizeof(BITREENODE)); pNewNode->data = ch; pNewNode->LTag = pNewNode->RTag = Link; /* 遞迴構建左右子樹 */ pNewNode->lchild = createBiTree(); pNewNode->rchild = createBiTree(); } return pNewNode; } /* 前序遍歷該二叉樹 */ void preOrderBiTree(BITREENODE* T) { if(T) { cout << T->data << " "; preOrderBiTree(T->lchild); preOrderBiTree(T->rchild); } } /* 中序遍歷線索化該二叉樹 */ BITREENODE* pre = NULL; //全域性變數,始終指向剛剛訪問過的節點 void InThreadBiTree(BITREENODE* T) { if(T) { /* 遞迴線索化左子樹 */ InThreadBiTree(T->lchild); /* 沒有左孩子 */ if(!T->lchild) { T->LTag = Thread; //前驅線索 T->lchild = pre; //左孩子指標,指向後繼 } /* 前驅沒有右孩子 */ if(pre != NULL && pre->rchild == NULL) { pre->RTag = Thread; //後驅線索 pre->rchild = T; //前驅的右孩子指向後繼 } /* 保持pre指向T的前驅 */ pre = T; /* 遞迴右子樹線索化 */ InThreadBiTree(T->rchild); } } /* 中序遍歷該線索二叉樹 */ void InOrderBiTree_Thread(BITREENODE* T) { BITREENODE* p = T; while(p != NULL) { /* 當LTag == 0時迴圈到中序序列第一個節點 */ while(p->LTag == Link) { p = p->lchild; } /*打印出該節點的數值*/ cout << p->data << " "; /* 打印出當前節點的後繼*/ while(p->RTag == Thread && p->rchild != NULL) { p = p->rchild; cout << p->data << " "; } /* 指向該節點的後繼 */ p = p->rchild; } cout << endl; } int main(void) { BITREENODE* pRoot = NULL; /* 建立二叉樹 */ pRoot = createBiTree(); /* 前序遍歷該二叉樹,這時候還沒有線索化二叉樹,可以這樣進行前序遍歷 */ preOrderBiTree(pRoot); cout << endl; /* 中序線索化該二叉樹 */ InThreadBiTree(pRoot); /* 前序遍歷該二叉樹,這時候已經中序線索化了二叉樹,就不可以這樣中序遍歷了 */ // preOrderBiTree(pRoot); InOrderBiTree_Thread(pRoot); return 0; }