二叉搜尋樹

2021-08-02 09:46:19 字數 3600 閱讀 7295

--------------------siwuxie095

二叉搜尋樹

這裡介紹二叉搜尋樹(binary search tree)

二叉搜尋樹,顧名思義,本質上也是一棵二叉樹

二叉樹在計算機中是一種非常常用的資料結構,選擇什麼型別的二叉樹

很多時候要根據需要解決的問題而定

使用資料結構的核心是要解決問題,而並非是為了使用資料結構而使用

資料結構

使用二叉樹並不是因為二叉樹很酷,很炫,聽起來很專業,而是因為二

叉樹能夠高效的解決一類問題

二叉搜尋樹解決的一類問題就是在計算機中非常常見的查詢問題

「查詢問題是計算機中非常重要的基礎問題」

可能很多人會覺得這個問題非常簡單,就是在一組資料中找到某

個資料,但是仔細想一想就會發現,查詢問題雖然描述出來很簡

單,但是它的應用卻非常廣泛

從去銀行辦理業務時,銀行根據證件號碼從系統中調出相應的信

息,到在

google 中搜尋內容時,google 根據關鍵字來查詢相

關的資訊 …

查詢問題,是乙個聽起來非常樸素,實際上卻非常困難,被研究

的非常廣泛的一類問題

「查詢問題,即 search problem」

二叉搜尋樹的優勢

事實上,二叉搜尋樹,通常都用於實現

查詢表有的地方,也稱

查詢表為

字典,如下:

key1

value1

key2

value2

key3

value3

key4

value4

key5

value5

即對於這些資料而言,都是乙個乙個鍵值對,即

key-value

對應的資料對,給你乙個

key,相應的就有乙個 value

這樣大量的資料對,集合在一起就形成了一張表,在這張表

中通過鍵(key)就能直接查到對應的值(value)

最典型的乙個應用就是字典。對於乙個字典來說,鍵(key)

就是乙個個單詞,而值(value)就是單詞的釋義

這也是查詢表有時候也被稱為字典這樣一種資料結構的原因

如果這些

key 都是整數,而且範圍比較小,那麼使用陣列就可以輕易

地用索引直接來索引到相應的

value

但在實際的業務邏輯中,很多時候不能用整數來表達這樣的鍵(key),

或者是因為這些鍵(key)相對比較稀疏,使用陣列在空間上並不經濟,

或者是因為這些鍵(key)壓根就不能用整數來表示

例如:字典的鍵(key)其實是乙個字串

這種情況下,就需要實現乙個查詢表,而實現查詢表的最基礎的乙個

方式是實現二叉搜尋樹

當然,也完全可以用

普通陣列

或順序陣列

來實現這個乙個查詢表

查詢元素

插入元素

刪除元素

普通陣列

o(n)

o(n)

o(n)

順序陣列

o(lgn)

o(n)

o(n)

二分搜尋樹

o(lgn)

o(lgn)

o(lgn)

可以簡單分析一下使用普通陣列

或順序陣列的時間效率:

1)使用普通陣列:

查詢乙個元素,就需要使用 o(n) 的時間從頭到尾遍歷一遍,看要找的

那個元素在陣列的什麼位置

插入乙個元素,也需要使用

o(n) 的時間從頭到尾遍歷一遍,因為對於

查詢表來說,需要先看一看當前查詢表中是否已經含有要插入的元素。

如果沒有,再插入;如果有的話,就應該是對

key 相應的

value 進行

乙個更新操作

刪除乙個元素,也需要使用 o(n) 的時間從頭到尾遍歷一遍,來刪除相

應的元素

2)使用

順序陣列:

要一直保證這個陣列是有序的。這樣一來,查詢乙個元素就可以使用

二分查詢法,用

o(lgn) 的時間進行查詢,但對於插入乙個元素和刪除

乙個元素來說,依然要使用

o(n) 的時間

相較而言,二叉搜尋樹就高效很多,它能夠保證查詢、插入、刪除這

三個操作的時間複雜度近乎都是

o(lgn) 級別的

所以,二叉搜尋樹的優勢:

1)高效

不僅可以高效查詢資料,還可以高效地插入資料、刪除資料

- 動態維護資料

也就是說,如果能一下就把所有的資料拿到手,那可能先對資料進行排序再

使用二分查詢法,就足夠了

但在很多時候,查詢、插入、刪除這三個操作,在業務的過程中都是要涉及

的,因此,二叉搜尋樹提供了乙個可以非常高效地動態維護資料的方式

2)可以方便地回答很多資料之間的關係問題,如下:

min、max、floor、ceil、rank、select

可以輕易地找到所有資料中的最小值

min、最大值 max,某個資料的

floor

相應的值、ceil 相應的值,還有給定乙個資料,求它的排名

rank,以及找

到所有資料中某排名(如:第 100 名)的資料

select

二叉搜尋樹的定義

如下圖所示,是一棵二叉搜尋樹:

二叉搜尋樹,是指一棵空樹

或者具有下列性質的二叉樹:

1)若任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值

2)若任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值

3)任意節點的左、右子樹也分別為二叉搜尋樹

4)沒有鍵值相等的節點

即1)每個節點的鍵值都大於左孩子

2)每個節點的鍵值都小於右孩子

不難看出,二叉搜尋樹的定義中天然就包含了遞迴結構

正因為如此,在對二叉搜尋樹程式設計時,很多時候都可以使用遞迴函式的方式,

方便快速地實現很多功能

注意:對於堆來說,堆的那棵二叉樹一定是一棵完全二叉樹,但對於二叉搜尋

樹來說,是沒有這個限制的,如下:

換句話說,上圖中的這棵樹,也是二叉搜尋樹,即

二叉搜尋樹,不一定是

完全二叉樹

在實現堆的時候,是利用了堆一定是一棵完全叉樹的特點,所以能用陣列

來表示堆,但二分搜尋樹不一定是完全二叉樹,所以用陣列表示並不方便

因此,通常是設立

node 節點,來表示 key-value 這樣的資料對,而節點

之間的聯絡,則使用指標的方式來表示

【made by siwuxie095】

二叉搜尋樹 二叉搜尋樹

題目 二叉搜尋樹 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 解釋 輸入為 ...