給定乙個公升序排序的陣列,將其轉化為平衡二叉搜尋樹(bst)。平衡二叉搜尋樹是指樹上的每個節點 node 都滿足左子樹中所有節點的的值都小於 node 的值,右子樹中所有節點的值都大於 node 的值,並且左右子樹的節點數量之差不大於1。
示例:輸入:nums = [-10,-3,0,5,9]
輸出:[0,-3,9,-10,null,5]
我們都知道對一顆二叉搜尋樹進行中序遍歷,得到的序列是乙個公升序排列的。所以給定的陣列是二叉搜尋樹的中序遍歷結果。下面我們來看一下如何根據二叉搜尋樹的中序遍歷來生成一顆高度平衡的二叉搜尋樹。
因為平衡二叉搜尋樹的左、右子樹的節點數量之差不大於1。所以,我們可以選擇陣列中中間的數字作為二叉搜尋樹的根節點。這樣就可以確保左右子樹的節點個數之差不大於1,從而使得樹時平衡的。如果給定的陣列長度是奇數,則根節點的選擇是唯一的,如果陣列的長度是偶數,則可以選擇中間位置左邊的數字作為根節點或者選擇中間位置右邊的數字作為根節點,選擇不同的數字作為根節點則建立的平衡二叉搜尋樹也是不同的。
在確定了平衡二叉搜尋樹的根節點之後,其餘的數字分別位於平衡二叉搜尋樹的左子樹和右子樹中,左子樹和右子樹分別也是平衡二叉搜尋樹,因此可以通過遞迴的方式建立平衡二叉搜尋樹。
根據選擇根節點的不同,我們可以有三種方法來構造平衡二叉搜尋樹。
方法一選擇中間位置左邊的數字作為根節點,則根節點的下標為 mid=(left+right) // 2。
#選擇中間位置左邊的數字作為根節點
mid = (left + right) // 2
root = treenode(nums[mid])
#遞迴求解左右子樹
root.left = cur(left, mid - 1)
root.right = cur(mid + 1, right)
return root
return cur(0, len(nums) - 1)
方法二:
選擇中間位置右邊的數字作為根節點,則根節點的下標為 mid=(left+right+1) // 2。
#選擇中間位置右邊的數字作為根節點
mid = (left + right + 1) // 2
root = treenode(nums[mid])
#遞迴求解左右子樹
root.left = cur(left, mid - 1)
root.right = cur(mid + 1, right)
return root
return cur(0, len(nums) - 1)
方法三
選擇任意乙個中間位置數字作為根節點,則根節點的下標mid在(left+right)//2 和 (left+right+1)/2 中隨機選擇乙個。
import random
class solution:
def sortedarraytobst(self, nums):
def cur(left, right):
if left > right:
return none
#選擇中間位置隨機乙個作為根節點
random_data= random.randint(0, 1)
mid = (left + right + random_data) // 2
root = treenode(nums[mid])
#遞迴求解左右子樹
root.left = cur(left, mid - 1)
root.right = cur(mid + 1, right)
return root
return cur(0, len(nums) - 1)
將有序陣列轉化為二叉搜尋樹
將乙個按照公升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。本題中,乙個高度平衡二叉樹是指乙個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。示例 給定有序陣列 10,3,0,5,9 乙個可能的答案是 0,3,9,10,null,5 它可以表示下面這個高度平衡二叉搜尋樹 0 3 9 10...
將二叉搜尋樹轉化為雙向鍊錶
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。建立的雙向鍊錶的順序就是二叉搜尋樹的中序遍歷結果。這裡有遞迴和非遞迴解法。一般的非遞迴解法需要開闢額外的空間,本次借助morris演算法,給出一種不需要額外空間開銷的非遞迴解法。首先是遞...
將二叉搜尋樹變平衡
題目描述 給你一棵二叉搜尋樹,請你返回一棵 平衡後 的二叉搜尋樹,新生成的樹應該與原來的樹有著相同的節點值。如果一棵二叉搜尋樹中,每個節點的兩棵子樹高度差不超過 1 我們就稱這棵二叉搜尋樹是 平衡的 如果有多種構造方法,請你返回任意一種。思路分析 1.先將二叉搜尋樹進行中序遍歷儲存在list中,是有...