讀古今文學網 > 算法神探:一部谷歌首席工程師寫的CS小說 > 21 二叉搜索樹的屬性 >

21 二叉搜索樹的屬性

「等等,」Frank說,「錯了。」

Socks剛剛插入了一個節點,他驚訝地抬起頭,問道:「什麼?」

「你剛剛插入的那個節點,」Frank說,「插錯地方了。」

Socks盯著樹:「但是63確實是大於60,所以需要將它加進右子樹啊。」

「但是它比它的祖父節點61都要大,所以應該把它加入到61這個節點的右子樹,你卻把它加入了左子樹。二叉搜索樹的一個關鍵屬性是左子樹中的所有節點的值都小於當前節點的值,而右子樹中的所有節點的值都要大於當前節點的值。」

「我知道。」Socks安靜地說。

「那它為什麼會在左子樹中?」Frank問。

「我犯了一個錯誤。」Socks說。

「你為什麼忘記將61與63進行比較?」Frank問。

「我……我是從60這個節點開始的。」Socks承認。

「什麼?」

「嗯,我最近一次插入的節點是60……63和60比較接近……所以我剛剛從節點60開始,就將其插入到了60的下面。」

「你沒有從樹根開始?」Frank嚷道。

「我想這樣會更快,」Socks說,「這樣可以跳過樹中大部分節點。」

「你最終把它放在了錯誤的地方!有多少個節點使用了這種投機取巧的方式?」

「有幾個吧。」Socks承認道。

Frank長歎一聲,便開始一連串的抱怨和咒罵。Socks盯著地面明智地沒有吭聲。

在他終於平靜下來後,Frank深吸了一口氣,重新開始觀察這棵樹。

「我們必須做一個窮舉搜索,」Frank從牙縫裡硬擠出了幾句話,「如果這棵樹沒能維持二叉搜索樹的屬性,我們就不能安全地做任何剪枝。我們必須檢查每個節點。

「嘿,」Socks突然說,「如果我們必須檢查每個節點後再把它插入到樹中,那我們為什麼不直接做一個窮舉搜索呢?」

「攤銷時間成本,」Frank說,「將來我希望使用這棵樹進行多次搜索。我猜測50天到70天才是我們應該搜索的範圍。當我們有更多依據時,我們可以再進行不同範圍的搜索。我們甚至可能要去做一些更加精確的搜索。構建樹的成本將在多次搜索中被平攤,這樣平均的時間成本就會比較低,總的時間成本也會比較低。攤銷時間成本是考慮了多次搜索的總體時間成本,從而將構建樹的成本分攤到很多次的搜索中。」

「哦,」Socks說,「像我的魔術按鈕樹。」

Frank本想用力搖晃這個年輕巫師並大喊「當然像按鈕樹了!它們兩個都是二叉搜索樹!」,不過他努力控制住了自己,只是無奈地嘲諷道:「當然了。」

「好主意,」Socks說,「未來我們可以節省大量的時間。」

「是『可能』會節省。」Frank糾正他。

「哦,」Socks說,「對。我破壞了這個樹,不是嗎?」

警用算法導論:二叉搜索樹Ⅴ

節選自Drecker教授講義

正如我們在講義中所看到的,我們可以使用二叉搜索樹的結構來進行有效的搜索。不僅如此,我們還可以往樹中添加和刪除節點。但是,每當我們更改了原有數據的結構時,必須要確保不能破壞二叉搜索樹的屬性,這非常重要。

對於二叉搜索樹,最重要的是時刻保持二叉搜索樹的屬性。該屬性規定(1)左子節點(及其所有左子節點)中的值小於或等於當前節點的值,以及(2)右子節點(以及其所有右子節點)中的值大於或等於當前節點的值。如果我們違反這個屬性,此時這棵樹就不再是一棵二叉搜索樹,我們也不能在搜索時進行任何剪枝。