二叉樹和鍊錶轉化的題主要分為兩類,即將二叉樹轉化成單鏈表或者雙向鍊錶,和單鏈表轉化成二叉樹,而這裡的二叉樹往往指的是bst-tree,而單鏈表的序列往往是bst-tree的中序序列,往往像這類題,需要用到樹的遞迴遍歷來做,我形象的稱它為「 借力打力」,就是說,按照它的函式形式遞迴解題即可,比如二叉樹轉單鏈表的題(題144),使樹flat的方式有多,比如單向牽引(題144),雙向牽引後root節點更新為最左的節點成為煉表頭節點(這個是《劍指offer》書上的題),轉化過程如下圖。
原題鏈結
1
/ \2 5
/ \ \
3 4 6
1
\ 2\3
\4\5
\6
解題思路:看懂題目樣例基本就看懂了題目所謂的in-place轉化的大致過程,其特徵是,將將左子樹和右子樹分別flat,然後將左子樹插入到root與右子樹的中間空擋。起初思路走岔了,按照《劍指offer》那題解,進入last指標,但是後來發現直接在原題形式上解是最方便的,last指標由flat之後的鍊錶掃瞄到末尾節點求得,然後在用last參與鏈結的拼接。下面也把《劍指offer》那題貼出來解一下,對比著看。
/**
* definition for a binary tree node.
* struct treenode
* treenode(int x) : val(x), left(nullptr), right(nullptr) {}
* treenode(int x, treenode *left, treenode *right) : val(x), left(left), right(right) {}
* };
*/class
solution
};
原題鏈結
解題思路:此題因為是轉換之後的是雙向鍊錶,所以我選擇附設兩個指標pre和last分別指向轉換之後的鍊錶的頭節點和尾節點,不過依稀記得《劍指offer》上給出的解答是附設了乙個指標last。本題的思路比較直接,先分別對左右子樹進行轉換,並帶回相應的pre和last指標,然後利用左右子樹的pre和last指標調整root節點位置並進行鍊錶的拼接,完成之後要更新root節點對應的鍊錶pre和last的位置(相當於帶回轉換的bst的pre和last),這裡在處理題114時作者對葉子節點左單獨的判斷,i.e.,當為葉子節點時,pre和last直接指向root(葉子節點),否則則根據節點左、右子樹的相應pre和last更新之,但是在處理此題的時,可以直接先將pre和last指向root節點(先預設假設其為葉子節點),然後在根據左、右子樹是否存在,相應更新之。同種方法本質是相同的,但是,針對葉子節點需要做單獨判斷,因為這個是pre和last指標更新的起點(否則它們會直接為空)。
/*
// definition for a node.
class node
node(int _val)
node(int _val, node* _left, node* _right)
};*/
class
solution
void
helper
(node *root, node*
&pre, node*
&last)
node *preleft =
null
,*lastleft =
null
; node *preright =
null
,*lastright =
null
;helper
(root-
>left, preleft, lastleft)
;helper
(root-
>right, preright, lastright)
; root-
>left = lastleft;
if(lastleft) lastleft-
>right = root;
root-
>right = preright;
if(preright) preright-
>left = root;
pre = last = root;
if(root-
>left) pre = preleft;
if(root-
>right) last = lastright;}}
;
總結樹轉鍊錶題的通用解法: 二叉樹轉雙向鍊錶
include using namespace std 樹節點 struct node typedef struct node link 構造樹 void insert tree link h,int t if h val t insert tree h left,t else insert tre...
二叉樹轉雙向鍊錶
1.a 遞迴轉化左子樹為雙向鍊錶 1.b 找出根結點的前驅節點 是左子樹的最右的節點 1.c 將上一步找出的節點和根結點連線起來 2,如果右子樹不為null,處理右子樹 和上面的很類似 1.a 遞迴轉化右子樹為雙向鍊錶 1.b 找出根結點的後繼節點 是右子樹的最左的節點 1.c 將上一步找出的節點和...
二叉樹轉雙向鍊錶
這是一道挺有趣的題,其解題的思路主要還是二叉樹的中序遍歷 先建立乙個頭結點list,然後通過中序遍歷二叉樹,把結點串起來即可!注意點 1 需要有乙個指標來指向上乙個已遍歷過的結點 2 如果不建立頭結點,在後面遍歷判斷時比較麻煩 include using namespace std struct n...