二叉搜尋樹或者是一棵空樹,或者是具有下列性質的二叉樹:
(1)若左子樹不空,則左子樹上所有結點的值均小於或等於它的根節點的值;
(2)若右子樹不空,則右子樹上所有結點的值均大於或等於它的根結點的值;
(3)左、右子樹也分別為二叉搜尋樹;
如圖(一顆長殘了的bst):
若根結點的關鍵字值等於查詢的關鍵字,返回根節點的值。
否則,若小於根結點的關鍵字值,遞迴查左子樹。
若大於根結點的關鍵字值,遞迴查右子樹。
若子樹為空,則查詢不成功。
假如我們要查詢60
從根節點50開始,50 < 60 往右子樹裡找,到65,65 > 60 往右子樹裡找,找到60
與查詢類似,判斷在左子樹還是右子樹,走到葉節點後直接新加乙個節點
如圖我們要插入48
48 < 50,去左子樹,到40
48 > 40,去右子樹,到45
48 > 45,45沒有子節點了,48成為45的右兒子
最小值:一直往左子樹里找
最大值:一直往右子樹裡找
前驅是第乙個比這個數小的值,後繼是第乙個比這個大的值
性質:
節點x的前驅一定沒有右兒子,可能有左兒子(若前驅y有右兒子z,z大於y小於x,那z就是x前驅)
節點x的後繼一定沒有左兒子,可能有右兒子(若前驅y有左兒子z,z小於y大於x,那z就是x前驅)
前驅:如果這個節點x有左子樹,就以左兒子為根,查詢左子樹的最大值
如果沒有左子樹(1):如果x為右兒子,前驅就是x的父親
(2):如果x為左兒子,前驅就是右父親的左父親(若沒有左父親,就一直往上找)
如圖:
50的前驅是45。(前驅是左子樹最大值)
45的前驅是40。(沒有左子樹且為右兒子,前驅是其父親)
60的前驅是50。(沒有左子樹且為左兒子,前驅是其右父親的左父親)
30沒有前驅。 【沒有左子樹且為左兒子,但在30的左父親(祖先)裡沒有有左父親的節點】
後繼:如果這個節點有右子樹,就以右兒子為根,查詢右子樹的最大值
如果沒有右子樹(1):如果x為左兒子,後繼就是x的父親
(2):如果x為右兒子,前驅就是左父親的右父親(若沒有右父親,就一直往上找)
同理如圖:
50的後繼是60。(前驅是右子樹里最小的)
60的後繼是65。(沒有右子樹且為左兒子,前驅是其父親)
45的後繼是50。(沒有右子樹且為右兒子,前驅是其左父親的右父親)
80無後繼。 【沒有右子樹且為右兒子,但在80的左父親(祖先)裡沒有有右父親的節點】
刪除有三種情況:
情況1:刪除點為葉節點
直接刪除
對於30,45,60,80這四個節點,即使刪掉也不會改變原樹的平衡,故直接刪掉
情況2:刪除點右乙個兒子
直接用兒子替換刪除點的位置
如70,因為以70為根的子樹均大於65,所以刪掉70後直接把70的兒子80接到70的位置並不會影響原樹的平衡
如果刪除點只有左兒子同理,所以刪除點只有乙個兒子的話可以直接用兒子替換刪除點
情況3:刪除點右兩個兒子
找到刪除點的後繼,用後繼代替刪除點,然後讓後繼的兒子替換後繼的位置(情況2)
假設我們要刪除65,那我們先找到65的後繼67,把67放到65的位置上(因為65的右子樹都大於65,所以67大於65的左子樹,又因為67在65的右右子樹里最小,所以67小於處67外的65的右子樹,滿足平衡條件),變成了這樣
根據後繼的性質,67沒有左子樹,只有乙個右子樹(乙個兒子),因為67到了65的位置,所以67的位置空了出來(被刪了),在加上67只有乙個兒子,這不就是情況2嗎,然後對67進**況2的刪除就可以了
二叉搜尋樹 二叉搜尋樹
題目 二叉搜尋樹 time limit 2000 1000 ms j a others memory limit 32768 32768 k j a others total submission s 6945 accepted submission s 3077 problem descripti...
二叉搜尋樹 修剪二叉搜尋樹
第一反應是重構,看來別人的解答發現,其實不用重構那麼複雜。treenode trimbst treenode root,int low,int high if root val high 下一層處理完左子樹的結果賦給root left,處理完右子樹的結果賦給root right。root left ...
樹 二叉樹 二叉搜尋樹
給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。假設乙個二叉搜尋樹具有如下特徵 節點的左子樹只包含小於當前節點的數。節點的右子樹只包含大於當前節點的數。所有左子樹和右子樹自身必須也是二叉搜尋樹。示例 1 輸入 2 13輸出 true 示例 2 輸入 5 14 3 6輸出 false 解釋 輸入為 ...