讀古今文學網 > 算法神探:一部谷歌首席工程師寫的CS小說 > 18 建造二叉搜索梯 >

18 建造二叉搜索梯

「沒想到我們會換密碼吧,Runtime先生?」Frank聽到身後的一個聲音問道。

Frank轉過頭去。眼前的那位密探正從容不迫地向他走來。Frank試圖站起來,但他的腳卻疼得要命。最終,他還是坐在了地上,轉過身去看著她。

「我沒想到Vinettee集團居然有能力換密碼。」Frank承認道,「這年頭想要找邪惡巫師都很困難了。我聽說撐到最後的邪惡巫師現在都開始賣椰子了。」

「的確很困難。很多邪惡巫師都逃跑了,或者改行從商了。但想找到一個也不是完全不可能。總之Vinettee集團找到了一個願意幫助他們,但同時也有求於他們的巫師。」

她向梯子的方向揮了揮手,說道:「當然,在建造二叉搜索梯陷阱上他並沒有Katia那麼有天賦,Katia在這方面簡直是一個藝術家。不過他的能力也足夠了。

「其實你差一點就走對了。你只走錯了一個梯子。現在的密碼是26。因為我們不想讓他改動太多的梯子,只改動一個,讓我們可以抓到那些試圖用舊密碼的人就夠了。真可惜。」

Frank在她說完之前一直保持著沉默。然後他問道:「你是誰?」

「我的名字並不重要。我是幫Vinettee集團做事的。」

「一個密探嗎?」

她聳了聳肩:「我只是搜集信息的人。你叫我什麼都行。」

「那你想從我這得到什麼?」

「當然是想讓你別多管閒事了。」

Frank仔細思考了一下。要讓自己放棄追查,僅僅讓梯子咬自己的腳很明顯是不夠的。眼前的密探顯然也知道這一點,所以看來她要麼會殺掉他,要麼會將他關起來。雖然這兩者都不怎麼理想,但Frank終歸還是希望自己不要被殺掉。

那個密探似乎看穿了他的想法,說道:「我本來以為二叉搜索梯陷阱已經足夠讓你放棄了,但現在看來這還不夠。」她走向26對應的梯子旁邊的那個梯子,並用手掌擊打了梯子的一截,梯子發出一聲悶響。緊接著她又擊打了梯子兩下,砰!砰!又是兩聲悶響。

「再見了,Runtime先生。」她說道,然後便目不回望地走了。

Frank疑惑地望著她走遠。緊接著,他的餘光注意到一絲動靜,定睛一看,梯子上的三根鐵橫桿掉了下來。過了一會兒,那些桿開始嘶嘶地向他蠕動——它們原來是鐵蛇。

Frank迅速地動了起來。那些鐵蛇雖然很危險,但它們爬得很慢。如果他能成功到達26號梯子那兒的話,他就還有救。由於他的腳依然很疼,他只好用手和膝蓋爬行著。接著,他用手拉著梯子讓自己站起來,並用身子靠在那個金屬梯子上。毫無疑問,爬上去的過程將會非常痛苦。

現在鐵蛇距離他只有幾英尺遠了。

Frank惱怒地嚎叫了一聲,起身爬上了梯子。其實那更像是在跳躍而不是在爬,因為他需要用那只未受傷的腳讓自己跳起來,然後再用雙手抓住上一級的梯子。每一步都伴隨著他左腳的一陣疼痛。

Frank終於爬了上去,他癱在了25號梯平台上。他一邊躺著調整自己的呼吸,一邊咒罵著二叉搜索梯,簡直無法想像自己曾經還覺得這種數據結構很美麗很優雅。之前在警察學院的時候,Frank還專門去過Alena辦的幾個展覽,而且他還去看過全世界僅有的一次二叉搜索樹表演。

那場表演的名字叫「建造梨子」。Alena讓三個巫師現場用魔法建了一個二叉搜索梯,將一堆藏畫按照其中梨子的數量整理和展示了出來。當年以梨子為中心的靜態畫非常流行。有人覺得這可能是因為那年蘋果的收成不太好。雖然對梨子的這種狂熱不及下一年對吐司雕塑的崇拜那麼令人尷尬,但是這段歷史在現在的藝術史課上也只是會被帶有一絲厭惡地匆匆帶過。

接著,七個助手一人拿著一幅畫著梨子的畫走進了展覽廳。他們按照畫中梨子的數量由少到多站好。每個人都將手中的畫舉在自己的臉前方,以掩飾自己對梨的狂熱。

第一個巫師上前了一步,他找出了最中間的那幅畫。那幅畫中畫著一張木桌,上面放了一杯牛奶和8個梨子。

「樹根上升!」那位巫師叫道。那一排畫便立刻分成了三組。左邊組裡的畫中的梨子數量都小於8,而右邊組裡的畫中的梨子數量都大於8。浮在這兩組上方的便是這個二叉搜索樹的樹根。這位巫師已經建好了這棵樹的第一層分支。

接下來,另外兩個巫師分別遞歸著分割了兩邊的畫,過程與之前一樣:每個巫師選出一堆畫中最中間的那個,並將剩下的畫分成了左右兩份。隨著他們的劃分,樹也就長出了新的分支。

在當時,整個表演看起來棒極了。但現在,坐在已經被變成武器的二叉搜索樹上面,Frank覺得這整個想法實在太愚蠢了。他簡直無法理解當時他為什麼會覺得這種遞歸分割畫的方式很有美感。

耳邊的嘶嘶聲將Frank的思緒帶回了現實。一條鐵蛇的頭爬上了平台,正在尋找Frank。眼前的蛇其實只是一條會動的鐵欄杆,它們沒有眼睛,沒有鼻子,也沒有嘴巴。Frank很不能理解它們到底是用什麼來尋找的。也許它們能感應到震動?

他想把蛇踢下去,但最終決定不這樣做。因為鐵蛇雖然並沒有嘴巴,但毒性卻難以置信得大。

Frank決定繼續撤退。他走到了上一層梯子旁邊,並將自己拉了上去。這時候他的腳踝已經沒有那麼疼了,所以他得以以一個正常的姿勢來爬這截梯子。

Frank一直向上爬著。一會兒便回到了頂層寫著50的那層平台。

他定了一會兒神兒,心中再一次開始咒罵二叉搜索梯。雖然沒有任何具體的理由,他現在堅信二叉搜索梯是一個愚蠢的設計。Frank滿意地點了點頭,爬回了街道上,逃離了那些鐵蛇。

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

節選自Drecker教授講義

你可以從一個排好序的數組中創建出一棵二叉搜索樹。你只需要不斷遞歸地將所有元素劃分成更小的集合。在每一層中,選擇最中間的那個元素作為那一層的節點。如果元素個數為偶數,那麼隨意選擇中間兩個元素中的一個就行。

創建好根節點之後,可以用同樣的方式來分割左邊的元素和右邊的元素。從概念上來說,我們將排好序的數組分成了左右兩個數組,並將同樣的算法作用於它們上面。

但實際在建造這棵樹的時候,我們不需要真正去分割或者複製這個數組。整個算法可以只使用一個數組,我們只要記錄好當前分支中最小和最大元素的下標編號就好了。