線索二叉樹

2021-10-23 05:22:45 字數 2240 閱讀 1294

二叉樹是一種非線性結構,遍歷二叉樹幾乎都是通過遞迴或者用棧輔助實現非遞迴的遍歷。用二叉樹作為儲存結構時,取到乙個節點,只能獲取節點的左孩子和右孩子,不能直接得到節點的任一遍歷序列的前驅或者後繼。

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

n個節點的二叉樹中含有n+1個空指標域。利用二叉樹中的空指標域 來存放在某種遍歷次序下的前驅和後繼 ,這種指標叫「線索」。這種加上了線索的二叉樹稱為線索二叉樹。

根據線索的性質的不同,線索二叉樹分為:前序線索二叉樹 , 中序線索二叉樹 , 後序線索二叉樹

/* 二叉樹的二叉線索儲存結構定義*/

typedef

enum

pointertag;

//link = 0表示指向左右孩子指標;thread = 1表示指向前驅或後繼的線索

typedef

struct bitnode

bitnode,

*bitree;

線索化的實質就是將二叉鍊錶中的空指標改為指向前驅或後繼的線索。由於前驅和後繼資訊只有在遍歷該二叉樹時才能得到,所以,線索化的過程就是在遍歷的過程中修改空指標的過程。

先序首先對於左子樹存在的節點,就不會有前驅;同樣,節點的右子樹存在,那麼不存在後繼。那麼我就先一直找尋節的左子樹,判斷左右子樹是否為空 , 為空了才會考慮前驅和後繼的問題。後繼倒是很好找(反正要遍歷二叉樹),那麼前驅的位置呢?如果遇到左子樹不存在的節點,怎麼才能找到已經已經掃面過得節點呢?所以我們需要建立乙個節點指標,每次記住上一次掃瞄的節點 。 對於右子樹就很好辦了 , 如果當前節點的前乙個節點不為空且右子樹不存在,那麼我們就放心大膽的鏈上吧 。然後迴圈得了。

bitnode* prev =

null

//記錄前乙個節點的指標為

以這個二叉樹為例,這個二叉樹先序為12435。其中2的右節點為空,3的左節點為空,45左右節點都為空。右節點為空,需要後繼,左節點為空需要前驅。

每次只會把當前節點的左子樹前驅鏈上,這一次的 後繼 不會在本次鏈上,當pcur指向下乙個節點的時候,才會把上一次的後繼鏈上

)//沒有左子樹

if(prev !=

null

&& prev->pright ==

null

)// 上乙個節點有沒有 右子樹

prev = root;

//前驅 , 每次記住上次的節點

//判斷root是否有左右孩子

if(root->ltag == link)

_preorderthreading

(root->pleft);if

(root->rtag == link)

_preorderthreading

(root->pright)

;}線索二叉樹更像是把一棵樹存在乙個雙向鍊錶裡面,讓每乙個節點按順序(先序,中序,後序)鏈結,左節點指向前乙個節點,右節點指向後乙個節點。所以最好的辦法是先把各個節點的順序搞清楚,然後用鍊錶放進去,互相指向就可以了我這裡只寫了前序的線索化,中序和後序是差不多的。可以參考下面幾位大佬的部落格。

二叉樹線索化以及線索化的先序、中序、後序遍歷

**中序遍歷的線索二叉樹

徹底理解線索二叉樹

線索二叉樹

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