將二叉搜尋樹原地轉換成排序的雙向鍊錶

2021-10-03 20:18:58 字數 1861 閱讀 3702

雙向鍊錶的每乙個節點有next和pre兩個指標,二叉樹的每個節點則有right和left兩個指標,其中next,right指標都指向的是比當前節點大的下乙個節點,pre和left指標則指向的是比當前節點小的前乙個節點,所以我們把二叉搜尋樹中的right指標當做雙向鍊錶的next指標,left則與pre對應,這樣通過中序遍歷改變指標的指向,就可得到乙個從小到大有序的雙向鍊錶。

這裡可以有兩種寫法,一種就是正常的左中右的中序遍歷方式,維護頭尾兩個指標。改變尾指標的指向將鍊錶串起來。

class

bst2dl

:def

__init__

(self)

: self.head =

none

self.tail =

none

defconvert

(self, root):if

not root:

return

self.convert(root.left)

ifnot self.head:

self.head, self.tail = root, root

else

:#前乙個尾節點的右孩子指向當前根節點,即雙向鍊錶中的後向指標next

#當前根節點的左孩子指向前乙個尾節點,即前向指標prev

self.tail.right, root.left = root, self.tail

self.tail = self.tail.right #更新尾節點

self.convert(root.right)

return self.head

第二種寫法,維護乙個頭指標即可,但是遍歷方式需要變成右中左這樣的「中序遍歷」,也就是從最右遍歷到最左,這樣的話,當遍歷到最小節點時,頭指標也剛好指向這個最小節點。這裡改變的就是頭指標的指向,其實兩種方式差不多。

class

solution

:def

convert

(self, root)

: head =

none

defhelper

(root)

:nonlocal head

ifnot root:

return

helper(root.right)

#右if

not head:

head = root #根

else

: root.right = head

head.left = root

head = root

#print(head.val)

helper(root.left)

#左 helper(root)

return head

#驗證第二種寫法

#從頭到尾列印節點

s = solution(

)head = s.convert(bst.root)

while head.right:

print

(head.val, end=

' -> '

) head = head.right

print

(head.val)

#從尾到頭列印節點

while head:

print

(head.val, end=

' -> '

) head = head.left

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7

7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 ->

將二叉搜尋樹轉換成排序的雙向鍊錶

二叉搜尋樹的中序遍歷得到的是乙個已排序的序列。因此可以仿照中序遍歷,依次訪問結點並改變結點的指向,使其構成乙個雙向鍊錶。在訪問當前結點之前,需要先訪問左子樹,並改變左子樹中的結點指向,使其構成雙向鍊錶。同時需要獲取左子樹構成雙向鍊錶的頭和尾結點。頭結點是整棵樹構成的雙向鍊錶的頭結點,而尾結點是左子樹...

二叉搜尋樹轉換成排序雙向鍊錶

因為二叉樹中,每個結點都有兩個指向子節點的指標。在雙向鍊錶中也有兩個指標,它們分別指向前乙個和後乙個結點。由於這兩種結點的結構相似,同時二叉搜尋樹也是一種排序的資料結構,因此在理論上可能實現二叉搜尋樹和排序鍊錶的雙向鍊錶的轉換。在搜尋二叉樹中,左子節點的值總小於父節點的值,右子節點的值總是大於父節點...

二叉樹搜尋樹轉換成排序雙向鍊錶

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。先簡單說一說二叉搜尋樹,二叉搜尋樹有乙個特點 根大於左子樹,小於右子樹。二叉搜尋樹的中序遍歷是有序的序列。如下的一棵搜尋二叉樹 轉換成有序雙向鍊錶就要對搜尋二叉樹進行中序遍歷 ...