--------------------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 解釋 輸入為 ...