邏輯結構:
用空分支指向前驅和後繼,如何線索化?
乙個結點如果有空指標,則左空指標指向其遍歷序列前驅,如果有右空指標指向遍歷序列後繼
typedef
struct tbtnode tbtnode;
中序線索化**:
//pre為p的父結點/前驅
void
inthread
(tbtnode *p,tbtnode *
&pre)
//把p右孩子指向p的後繼
//我們採用pre指向p來連線(為什麼不用p來指向p的後繼呢,因為我們沒有p的後繼這個變數)
if(pre !=
null
&& pre-
>rchild ==
null
)//pre與p同步,那麼p是如何再領先pre到下一步呢,
//當遞迴結束,p回溯,就實現了p走到pre的下一步了
中序線索二叉樹:
開頭:最左的左孩子
結尾:最右的右孩子
給乙個結點如何找到它遍歷的前驅和後繼
找前驅
:從這個結點左走一步,再一直往右走到底。
比如:a1的前驅,左走一步a2,然後一直右走,是a5。
找後繼
:從這個結點右走一步,再一直往左走。
比如:a1的後繼,右走一步a3,再一直左走,是a6。
邏輯結構相似,遍歷方式不一樣。
乙個結點如果有空指標,則左空指標指向其遍歷序列前驅,如果有右空指標指向遍歷序列後繼
//pre為p的父結點/前驅
void
prethread
(tbtnode *p,tbtnode *
&pre)
//把p右孩子指向p的後繼
//我們採用pre指向p來連線(為什麼不用p來指向p的後繼呢,因為我們沒有p的後繼這個變數)
if(pre !=
null
&& pre-
>rchild ==
null
)//pre與p同步,那麼p是如何再領先pre到下一步呢,
//當遞迴結束,p回溯,就實現了p走到pre的下一步了
pre = p;
//左指標不是線索,才往左走,避免繞圈陷入死迴圈
第乙個結點是根結點。找後繼結點,如果乙個結點的左指標不空,並且左指標不是線索,那麼左指標指向其後繼(是線索的話就指向其前驅了)。如果乙個結點其左指標空,其右指標一定指向指向其後繼結點(普通和線索一樣)
void
preorder
(tbtnode *tbt)
//右指標指向的是後繼
}}
後序考點:
**的記法:
1.初始狀態
初始:p = a1, pre = null
2.兩個連線的if語句
if(p->lchild == null)
if(pre != null && pre->rchild == null)
兩個if() 放***thread()前面叫前序,放中間叫中序,放最後叫後序.
3.只有前序前面需要加if(p->xtag == 0)來判斷(避免形成環),中序不需要這個if。
//只有前序線索才需要檢測是否有環
if(p-
>ltag ==0)
xxthread
(p->lchild,pre);if
(p->rtag ==0)
xxthread
(p->rchild,pre)
;
當兩個if都放在inthread()前面就是前序線索二叉樹的**,兩個if都放在兩個inthread ()中間,就是中序線索二叉樹的**。
前序:找後繼結點方便,但不方便找前驅結點
(比如:a2->a1,只知道a2如何找a1)
中序:前驅和後繼都能很方便的找到。
找前驅
:從這個結點左走一步,再一直往右走到底。
找後繼
:從這個結點右走一步,再一直往左走。
(在前面有)
後序:找前驅和找後序都複雜。(具體過程在前面的總結)
(所有找前驅,考研考的相當少,幾乎不考,主要考的是找後繼的方法)
樹與二叉樹 線索二叉樹
若結點有左子樹,則其lchild域指向其左子樹,否則令lchild域指向其前驅 若結點有右子樹,則其rchild域指向其右子樹,否則令rchild域指向其後繼 為了避免混淆,需要改變結點結構,增加兩個標誌域,ltag,rtag,結構如下圖所示 0 lchild域指向其左子樹 1 lchild域指向其...
線索二叉樹
當用二叉鍊錶作為二叉樹的儲存結構時,因為每個結點中只有指向其左 右兒子結點的指標,所以從任一結點出發只能直接找到該結點的左 右兒子。在一般情況下靠它無法直接找到該結點在某種遍歷序下的前驅和後繼結點。如果在每個結點中增加指向其前驅和後繼結點的指標,將降低儲存空間的效率。我們可以證明 在n個結點的二叉鍊...
線索二叉樹
1.線索二叉樹結構和操作定義 threadbintree.h 功能 線索標誌域所有值 typedef enumnodeflag 功能 線索二叉樹結構體 typedef struct threadtreethreadbintree 前驅節點指標 threadbintree previous null ...