面試題36 二叉搜尋樹與雙向鍊錶

2021-10-04 06:15:00 字數 2823 閱讀 8850

輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的迴圈雙向鍊錶。要求不能建立任何新的節點,只能調整樹中節點指標的指向。

為了讓您更好地理解問題,以下面的二叉搜尋樹為例:

我們希望將這個二叉搜尋樹轉化為雙向迴圈鍊錶。鍊錶中的每個節點都有乙個前驅和後繼指標。對於雙向迴圈鍊錶,第乙個節點的前驅是最後乙個節點,最後乙個節點的後繼是第乙個節點。

下圖展示了上面的二叉搜尋樹轉化成的鍊錶。「head」 表示指向鍊錶中有最小元素的節點。

特別地,我們希望可以就地完成轉換操作。當轉化完成以後,樹中節點的左指標需要指向前驅,樹中節點的右指標需要指向後繼。還需要返回鍊錶中的第乙個節點的指標。

分析:由於這個題目已經是二叉搜尋樹,所以轉換成有序的鍊錶很容易,對於當前節點來說,它的前驅一定是它左子樹最右邊的節點,它的後繼一定是它的右子樹最左邊的節點。發現這一點後,會發現其實這就是中序遍歷的順序嘛,於是只需要稍稍修改中序遍歷的**即可。

基本思路是分別用pre_node, node表示上一次訪問的節點和當前訪問節點,則pre_node.right=node, node.left=pre_node。但是如何得到上一次遍歷訪問的節點,到底是用遞迴還是用棧的實現方式呢?

遞迴寫起來簡單,但是我沒想到怎麼記錄上次訪問的節點,於是一開始我選擇在中序遍歷棧的寫法上修改。中序遍歷棧的寫法可參見我之前的部落格

法一:

"""

# definition for a node.

class node:

def __init__(self, val, left=none, right=none):

self.val = val

self.left = left

self.right = right

"""class

solution

:def

treetodoublylist

(self, root:

'node')-

>

'node'

:if root==

none

:return

none

stack=

node=root

first_node=

none

pre_node=

none

while stack or node:

while node:

node=node.left

node=stack.pop(

)if pre_node!=

none

: pre_node.right=node

node.left=pre_node

else

: first_node=node

pre_node=node

node=node.right

first_node.left=pre_node

pre_node.right=first_node

return first_node

後來看了看劍指offer書上的解法,方法和我的差不多,只不過用遞迴實現的,用全域性變數來表示pre_node。一直以來我比較牴觸在遞迴裡面修改全域性變數,因為一般情況下會導致每次遞迴時全域性變數變得面目全非,把自己給繞進去了。不過,由於二叉樹遞迴呼叫的順序還是很清楚的,因此在這裡用乙個pre_node全域性變數也還是可以分析清楚它的變化的。

法二:

"""

# definition for a node.

class node:

def __init__(self, val, left=none, right=none):

self.val = val

self.left = left

self.right = right

"""class

solution

:def

recursive

(self, node)

:if node==

none

:return

self.recursive(node.left)

if self.pre_node!=

none

: self.pre_node.right=node

node.left=self.pre_node

else

: self.first_node=node

self.pre_node=node

self.recursive(node.right)

deftreetodoublylist

(self, root:

'node')-

>

'node'

:if root==

none

:return

none

self.pre_node=

none

self.first_node=

none

self.recursive(root)

self.first_node.left=self.pre_node

self.pre_node.right=self.first_node

return self.first_node

會中序遍歷之後so easy~~

面試題36 二叉搜尋樹與雙向鍊錶

面試題36 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。調整指標 原先指向左子節點的指標調整為鍊錶中指向前乙個節點的指標 原先指向右子節點的指標調整為鍊錶中指向後乙個節點的指標 如何調整 考慮根節點和左右子樹的根本情況,因為如果用...

面試題36 二叉搜尋樹與雙向鍊錶(分治)(遞迴)

題目 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的迴圈雙向鍊錶。要求不能建立任何新的節點,只能調整樹中節點指標的指向。為了讓您更好地理解問題,以下面的二叉搜尋樹為例 我們希望將這個二叉搜尋樹轉化為雙向迴圈鍊錶。鍊錶中的每個節點都有乙個前驅和後繼指標。對於雙向迴圈鍊錶,第乙個節點的前驅是最後乙個...

面試題24 二叉搜尋樹與雙向鍊錶

分析 1.二叉樹中,每個結點都有兩個指向子結點的指標。2.在雙向鍊錶中,每個結點也有兩個指標,分別指向前乙個結點和後乙個結點 3.二叉搜尋樹中,左子結點的值總是小於父結點的值,右子結點的值總是大於父結點的值。4.將二叉搜尋樹轉換為雙向鍊錶時,原先指向左子結點的指標調整為鍊錶中指向前乙個結點的指標,原...