線索二叉樹

2022-09-04 23:30:25 字數 1689 閱讀 8614

要找到指定節點p在中序遍歷序列中的前驅:

再次遍歷,設定兩個工作指標pre和q分別指向前乙個訪問的結點和當前訪問的結點

直到q指向指定結點p,此時pre即為前驅

n個結點的二叉樹擁有(n+1)個空鏈域,利用這些空鏈域來提供線索,即形成了線索二叉樹

顯然,只有具有空鏈域的結點可以在 o(1) 時間內根據線索找到結果

實際上在中序遍歷中上圖綠框的檢查是不必要的,因為中序遍歷下最後乙個結點的右孩子必定為空,所以處理到最後乙個結點時可以直接將 rtag置為1

按照類似的思路,我們來看看先序線索化:

注意!!!:在構建前後繼關係時,能依靠的只有兩個工作指標preq,即只能通過這兩個指標來確定已知的前後繼關係(pre是 q的前繼,q是 pre的後繼)

因此,需要關注線索的讀寫順序,例如在先序遍歷中,由於 visit 發生在遞迴左子樹之前,如果 visit 將本來為null的q的左孩子修改為了指向pre的線索,就會形成死迴圈

為何只會在先序遍歷**現上述「轉圈現象」呢?從下面的訪問次序就可以看出

中序:左 根

後序:

先序:根 左右 只有在先序中對根的操作先於左孩子,相當於發生了讀後寫衝突(本來期望在讀到左孩子為null後再對根線索化)

解決方法如下:在遞迴線索化左子樹之前先判斷左孩子是否已經是線索( ltag == 0 ?):

這裡就要注意對最後乙個結點的處理,因為後序遍歷下最後訪問的結點是可能有右孩子的

=== 後序注意尾結點判斷,先序注意死迴圈 ===

線索二叉樹

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