劍指offer 二叉搜尋樹相關內容

2021-10-03 20:25:10 字數 3221 閱讀 5182

首先明確二叉搜尋樹的概念

中序遍歷是由小到大排序的(因此對於此二叉樹轉化雙向排序列表、尋找第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 輸入乙個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如...