線索二叉樹

2021-09-26 06:35:07 字數 2090 閱讀 6288

通過二叉樹及其遍歷演算法我們了解到:

二叉樹的遍歷過程較為複雜,需要用到遞迴和棧;

二叉樹的節點遍歷序列是乙個線性序列;

二叉鍊錶難以找到前驅後繼節點資訊;

二n個結點的二叉鍊錶中,有2n個指標域{n-1個非空指標域,n+1個空指標域}

【4注】證明:可以參考這位大佬的證明-->

那麼我們能不能利用空指標域,指向遍歷序列中的前驅、後繼節點,從而不再需要借助棧和遞迴也能方便的實現二叉樹的遍歷

-----------------------------------------於是聰明的「古人」發明了『線索二叉樹』------------------------------------

首先,什麼是二叉樹的線索化,為什麼要對二叉樹線索化?

【答】二叉樹是一種非線性結構,遍歷二叉樹幾乎都是通過遞迴或者用棧輔助實現非遞迴的遍歷。

用二叉樹作為儲存結構時,取到乙個節點,只能獲取節點的左孩子和右孩子,不能直接得到節點的任一遍歷序列的前驅或者後繼。

為了儲存這種在遍歷中需要的資訊,我們利用二叉樹中指向左右子樹的空指標來存放節點的前驅和後繼資訊,就能實現二叉樹的線索化

1. 指向遍歷序列前驅、後繼節點的指標成為線索

2.把空指標修改為線索的過程成為線索化;

3.經過線索化的二叉樹稱為線索二叉樹;

4.含有線索的二叉鍊錶叫做線索鍊錶;

【注】:ltag{0:指示該結點的左孩子; 1:指示該結點的前驅節點}

rtag{0:指示該結點的右孩子; 1:指示該結點的後繼節點}

先序二叉樹         2. 中序二叉樹        3. 後序二叉樹

我用藍色標識前驅,綠色標識後繼,不知道怎麼的上傳後這麼模糊。。)

一直進行下去,最後是這樣的:(下次還是找網圖吧…自己畫好醜~)

(p and pre)始終動態變化,但還是互為前驅後繼。

在修改過程中:若p->lchild為空,則將ltag修改為指示前驅節點pre;若pre->rchild為空,則修改為指向後繼節點p;

因此我們的中序線索化演算法就呼之欲出啦~:

void inthread(bitree p)

if(pre->rchild==null)

pre=p;//記得動態變化

inthread(p->rchiild); //線索化右子樹

}}

在中序遍歷中,第乙個結點是樹中處於「最左下方」的節點,從根沿著左孩子指標一直遍歷到沒有左孩子的節點即為所求。

bitnode *infirst(bitree root)

while(p->ltag==0)

return p;

}

1.若當前訪問的節點無右孩子,則rchild指向後繼

2.若有右孩子,右子樹中「最左下端」節點即為其後繼節點(such as :a有右孩子,他的後繼為e)

bitnode *innext(bitnode *p) 

else

return next;

}

那麼中序線索二叉樹的遍歷演算法就是:--->

void ldr(bitree root)

}

input  :      1. abc##de#g##f###         2.abd#g###ce#h##f##output:  -->c-->b-->e-->g-->d-->f        -->d-->g-->b-->a-->e-->h-->c

線索二叉樹

當用二叉鍊錶作為二叉樹的儲存結構時,因為每個結點中只有指向其左 右兒子結點的指標,所以從任一結點出發只能直接找到該結點的左 右兒子。在一般情況下靠它無法直接找到該結點在某種遍歷序下的前驅和後繼結點。如果在每個結點中增加指向其前驅和後繼結點的指標,將降低儲存空間的效率。我們可以證明 在n個結點的二叉鍊...

線索二叉樹

1.線索二叉樹結構和操作定義 threadbintree.h 功能 線索標誌域所有值 typedef enumnodeflag 功能 線索二叉樹結構體 typedef struct threadtreethreadbintree 前驅節點指標 threadbintree previous null ...

線索二叉樹

原始碼 中序線索二叉樹 author 菜鳥 version 2014.7.23 include include include typedef char datatype using namespace std 定義線索二叉樹的結構體 typedef struct nodethreadbitreen...