首先明確二叉搜尋樹的概念中序遍歷是由小到大排序的(因此對於此二叉樹轉化雙向排序列表、尋找第k小的數值、排序類問題都是非常重要的) ;
後續遍歷最後的節點是根節點,那麼左邊的部分的前一部分比根節點小,後一部分比根節點大,這就能找到左右子樹。(基於這個的我們可以重構二叉樹、也可以判定給定乙個後序遍歷它是不是某一顆二叉樹的後序遍歷)
給定一棵二叉搜尋樹,請找出其中的第k小的結點。例如, (5,3,7,2,4,6,8) 中,按結點數值大小順序第三小結點的值為4。思路就是直接按照上面的性質 + 二叉樹的基本中序遍歷 得到第k小的數值。本質上考察的就是二叉樹+變形。
def kthnode(self, prootoftree, k):
# 注意k == 0,表示沒開始數
if prootoftree == none or k == 0:
return none
tempnode = prootoftree
stack =
while tempnode or stack:
while tempnode:
tempnode = tempnode.left
tempnode = stack.pop()
if k == 1:
return tempnode
k -= 1
tempnode = tempnode.right
return none
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。思路就是上述性質發現中序遍歷結果連起來剛好是題目的要求,那麼我們就考慮將頭節點和左右子樹聯結器,那麼就是二叉樹遞迴中序列遍歷的基礎上,連線左右子樹然後當前最右節點。但是發現對於左子樹可以,返回最大值,下次直接拼接後面的就可以。但是對於右子樹,我們需要返回最左側,才能和根結點拼起來。想來想去,最後發現返回根節點即可,然後返回的如果是左子樹,就右根結點移動到最右側,如果是右子樹,就由根節點移動到最左側,然後結合當前的根結點拼起來,再次返回當前根節點,這就是整個思路。
可以發現能解除此題 就是 性質 + 二叉樹的基本模板。屬於上乙個部落格的第二點。
# 首先發現搜尋二叉樹的中序遍歷就是由小到大排序的
# 本質上就是將二叉樹的中序遍歷構造乙個雙向列表,且不申請新的記憶體空間
class solution:
def convert(self, prootoftree):
# write code here
if prootoftree == none:
return none
def midwatch(prootoftree):
if prootoftree == none:
return none
left = midwatch(prootoftree.left)
pnode = prootoftree
right = midwatch(prootoftree.right)
if left:
while left.right:
left = left.right
left.right = pnode
if right:
while right.left:
right = right.left
right.left = pnode
pnode.right = right
pnode.left = left
return pnode
輸入乙個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出yes,否則輸出no。假設輸入的陣列的任意兩個數字都互不相同。題目思路:就是上述搜尋二叉樹的性質2,通過後序遍歷能重構二叉樹,那麼考慮不能重構的原因就是左子樹裡面有比根結點大的 or 右子樹裡面有比根節點小的,這就是思路。那麼思路來了,直接按照 上乙個部落格講的那個遞迴方法就可以構造不斷獲取左右子樹的list進行判斷了。本質上還是 性質 + 模板 + 遞迴的模板。
def verifysquenceofbst(self, sequence):
# write code here
# 可以為空;子樹也是二叉搜尋樹; 但本程式不符合
# 如左右子樹不空,那麼左子樹的值均小於根節點,右子樹的值均大於根節點
if sequence == :
return false
# 這東西是資料結構,為什麼要有這種樹呢?根本的原因就是為了加快查詢的速度,才引入了這種樹。
def digui(sequence):
if len(sequence) <= 1: # 1個節點或者沒有節點為true
return true
node = sequence[-1]
i = 0
# 用while迴圈可以分隔開2個元素的list
while i < len(sequence) - 1:
if sequence[i] > node:
break
i += 1
# 注意切片在範圍溢位時候返回空陣列,不會發生indexerroe錯誤
seqsmall = sequence[:i]
seqlarge = sequence[i:-1]
# 下面幾行可以優化,從時間複雜度上考慮的話,問題不大
for j in seqsmall:
if j > node:
return false
for k in seqlarge:
if k < node:
return false
return digui(seqsmall) and digui(seqlarge)
return digui(sequence)
對上面的一種補充:可以發現二叉搜尋樹是二叉樹的一種特殊形式,它具備二叉樹的那些基礎模板,我們可以用二叉樹的基礎模板去實現這樣的二叉搜尋樹,同時它又具有自己獨特的特性,如上面講述的2個點,本質上而言,二叉搜尋樹是二叉樹的一種應用。因此它的解題思路和二叉樹的基本思路模板大同小異。只會在其基礎上進行一些擴充套件,往往反應在**上就是邏輯的一些思想上的不同,但基本的實現架構師一樣的。
劍指offer 二叉樹 二叉樹搜尋樹
package bst import j a.util.public class bst if pre.length 0 in.length 0 treenode root new treenode pre 0 for int i 0 i in.length i return root 判斷給定陣列...
劍指offer 二叉樹 二叉搜尋樹的後序遍歷
輸入乙個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出yes,否則輸出no。假設輸入的陣列的任意兩個數字都互不相同。例如輸返回true 輸入返回false 1,利用二叉搜尋樹左 中 右的特性,和後序遍歷的特點 2,後序遍歷為左右根,則陣列末尾為根,然後依據大小找出左子樹和右子樹...
劍指Offer 二叉搜尋樹的後序遍歷
輸入乙個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出yes,否則輸出no。假設輸入的陣列的任意兩個數字都互不相同。author zy date 2017年10月13日 下午9 34 21 decription 輸入乙個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如...