輸入一顆二元查詢樹,將該二元查詢樹轉換成乙個排序的雙向鍊錶。要求不能有新的結點,只能調整結點的指向。
由於轉換後的雙向鍊錶中結點的順序與二叉樹的中序遍歷相同,因此,可以對二叉樹的中序遍歷演算法進行修改,通過在中序遍歷的過程中修改結點的指向來轉換成乙個排序的雙向鍊錶。
# -*- coding:utf-8 -*-
class bitnode():
def __init__(self):
self.data = none
self.lchild = none
self.rchild = none
class test():
def __init__(self):
self.phead = none #雙向煉表頭結點
self.pend = none #雙向鍊錶尾結點
#方法功能:把有序陣列轉化為二叉樹
def arrytotree(self,arr,start,end):
root = none
if end >= start:
root = bitnode()
mid = int((start+end)/2)
#樹根節點為陣列中間元素
root.data = arr[mid]
#遞迴用左半部分陣列構造root左子樹
root.lchild = self.arrytotree(arr,start,mid-1)
#遞迴用右半部分陣列構造root右子樹
root.rchild = self.arrytotree(arr,mid+1,end)
else:
root = none
return root
'''方法功能:把二叉樹轉換為雙向鍊錶
輸入引數:root--二叉樹根節點
'''def inorderbdtree(self,root):
if root == none:
return
#轉換root左子樹
self.inorderbdtree(root.lchild)
root.lchild = self.pend #使當前結點左孩子指向雙向鍊錶中最後乙個結點
if none == self.pend: #雙向鍊錶為空,當前遍歷結點為雙向煉表頭結點
self.phead = root
else: #使雙向鍊錶最後乙個結點右孩子指向當前結點
self.pend.rchild = root
self.pend = root #將當前結點設為雙向鍊錶最後乙個結點
#轉換root右子樹
self.inorderbdtree(root.rchild)
if __name__ == "__main__":
arr = [1,2,3,4,5,6,7,8,9]
test = test()
root = test.arrytotree(arr,0,len(arr)-1)
test.inorderbdtree(root)
print("轉化後雙向鍊錶正向遍歷:")
cur = test.phead
while cur != none:
print(cur.data)
cur = cur.rchild
print("轉化後雙向鍊錶逆向遍歷:")
cur = test.pend
while cur != none:
print(cur.data)
cur = cur.lchild
執行結果:
轉化後雙向鍊錶正向遍歷:12
3456
789轉化後雙向鍊錶逆向遍歷:98
7654
321
與二叉樹中序遍歷類似時間複雜度為o(n),此方法用了兩個額外的變數phead與pend記錄雙向鍊錶首尾結點,因此,空間複雜度為o(1) 樹轉化為二叉樹 森林轉化為二叉樹(詳解版)
前面介紹了普通樹轉化為二叉樹的孩子兄弟表示法,本節來學習如何將森林轉化為一整棵二叉樹。森林,指的是由 n n 2 棵互不相交的樹組成的集合,如圖 1 所示。在某些實際場景中,為了便於操作具有森林結構的資料,往往需要將森林轉化為一整棵二叉樹。我們知道,任意一棵普通樹都可以轉化為二叉樹,而森林是由多棵普...
把排序陣列轉化為高度最小的搜尋二叉樹
給乙個排序陣列 從小到大 將其轉換為一棵高度最小的排序二叉樹。樣例 給出陣列 1,2,3,4,5,6,7 返回 4 2 6 1 3 5 7 二叉搜尋樹是左子樹的值比根結點小,根結點的值比右子樹小的樹 假設左右子樹都存在的話 因此利用遞迴以及二分的思想,把給定的排序陣列找到中間值給根結點,中間值前面的...
將二叉樹按照層級轉化為鍊錶
給一棵二叉樹,設計乙個演算法為每一層的節點建立乙個鍊錶。也就是說,如果一棵二叉樹有d層,那麼你需要建立d條鍊錶。樣例 1 輸入 輸出 1 null,2 3 null,4 null 解釋 1 2 3 4樣例 2 輸入 輸出 1 null,2 null,3 null 解釋 1 2 3 definitio...