1 折半查詢法瞭解二叉查詢樹之前,先來看看折半查詢法,也叫二分查詢法 在一個有序的整數陣列中(假如是從小到大排序的),如果查詢某個元素,返回元素的索引。如下:思想很簡單: 1 先找
2021-07-11 03:08:59
瞭解二叉查詢樹之前,先來看看折半查詢法,也叫二分查詢法 在一個有序的整數陣列中(假如是從小到大排序的),如果查詢某個元素,返回元素的索引。
如下:
思想很簡單: 1 先找到陣列中間元素target與6比較 2 如果target比6大,就在陣列的左邊查詢 3 如果target比6小,就在陣列的右邊查詢
java實現程式碼如下:
測試程式碼如下:
折半查詢的關鍵是陣列必須有序,一次過濾掉一半的資料,時間複雜度為O(logN)。 上面是以2為底的,N為陣列的元素個數.
折半查詢和下面的要講的二分搜尋樹是有一樣的思想
二分搜尋樹定義雙叫二分查詢樹,其定義如下 1 若它的左子樹不為空,則左子樹上所有的節點的值均小於根結點的值 2 若它的右子樹不為空,則右子樹上所有的節點的值均大於根結點的值 3 它的左右子樹也分別為二分搜尋樹
由二叉搜尋樹的定義可知,它前提是二叉樹,並且採用了遞迴的定義方式 。再得,它的節點滿足一定的關係,左子樹的節點一定比父節點的小, 右子樹的節點一定比父節點的大。
構造一棵二叉搜尋樹的目的,其實目的不是為了排序,是為了提高查詢,刪除,插入關鍵字的速度。
下面我們用圖和程式碼來解釋二叉樹的查詢,插入,和刪除。比如下圖就是一個二叉搜尋樹
二叉搜尋樹中存放的都是key。先看下二叉樹的定義
二叉樹中節點的定義類的定義和類中節點的定義都有了。 二分搜尋樹的定義如下:1 如果這棵樹為空,新建一個節點,作為根 2 如果要插入的key比根節點大,就插入到右子樹中 3 如果要插入的key比根節點小,就插入到左子樹中 4 如果要插入的key和根節點相等,就更新當前節點的value 程式碼如下:
和上面向一棵二叉搜尋樹插入一個節點一樣。 向一棵二叉搜尋樹中查詢一個節點也是類似 1 如果根節點為空,不用查找了,返回null 2 如果key比根節點的key要大,在右子樹中查詢 3 如果key比根節點的key要小,在左子樹中查詢 4 如果key和根節點的key相等,返回根節點
程式碼實現如下:
根據根節點的訪問順序,可以把遍歷分為前序遍歷,中序遍歷,後序遍歷 前序遍歷:先訪問根節點,再前序遍歷左右子樹 中序遍歷:先中序遍歷左子樹,再訪問根節點,後中序遍歷右子樹 後序遍歷:先後序遍歷左子樹,再後序遍歷右子樹,再訪問根節點
二叉樹的遍歷有前序遍歷,中序遍歷,後序遍歷,層序遍歷(也叫做廣度優先遍歷) 如下圖的二叉搜尋樹。
根據根節點的訪問順序,可以把遍歷分為前序遍歷,中序遍歷,後序遍歷 前序遍歷:先訪問根節點,再前序遍歷左右子樹 中序遍歷:先中序遍歷左子樹,再訪問根節點,後中序遍歷右子樹 後序遍歷:先後序遍歷左子樹,再後序遍歷右子樹,再訪問根節點
二叉樹的遍歷有前序遍歷,中序遍歷,後序遍歷,層序遍歷(也叫做廣度優先遍歷) 如下圖的二叉搜尋樹。
程式碼實現分別如下:
其中層序遍歷就是一層一層的從左到右遍歷 上圖中層序遍歷的結果是 13 6 15 3 7 10 18 程式碼實現需要藉助佇列,程式碼實現如下:二叉搜尋樹最麻煩的就是刪除節點,刪除任意二叉樹中的節點之前,我們來先刪除特殊的節點。
刪除二叉搜尋樹中最小的節點
刪除二叉搜尋樹中最大的節點
查詢二叉搜尋樹中最小的節點
查詢二叉搜尋樹中最大的節點
我們先來實現這些操作。
如下圖
根據二叉搜尋樹的定義,可以得出以下結論
在一個二叉搜尋樹中,最小的節點一定是最左邊的節點,也就是圖中的節點 3
在一個二叉搜尋樹中,最大的節點一定是最右邊的節點,也就是圖中的節點 18
總之: 最小節點去左子樹中找,直到節點的左孩子為空,則當前節點就是最小節點 最大節點去右子樹中找,直到節點的右孩子為空,則當前節點就是最大節點
1 先來實現查詢二叉搜尋樹中最小的節點 如下程式碼
同理,查詢最大節點也是一樣 2 實現查詢二叉搜尋樹中最大的節點 程式碼如下:
上面實現了查詢最小節點和最大節點,下面我們再來實現刪除最小節點和刪除最大節點
3 實現刪除二叉搜尋樹中最小的節點 一直往左孩子中刪除,當某一個節點node沒有左孩子時,說明當前節點就是最小節點 這時候分兩種情況
當前節點有右孩子 如果是這種情況,直接把右孩子返回,作為當前節點
當前節點沒有右孩子 如果是這種情況,直接返回null。此時返回右孩子也行,因為右孩子也是null
程式碼實現如下
同理,刪除二叉搜尋樹中最大的節點的程式碼如下:
下面來分析一下刪除任意一個節點。 刪除任意一個節點node,那麼可以分為以下幾種情況
node 沒有孩子
node 只有一個孩子
node 有兩個孩子
如下圖一棵二叉搜尋樹,我們來分析
第一種情況:node沒有孩子 這種情況最簡單,直接刪除就行了,剩下的還是一棵二叉搜尋樹 比如圖中的 節點5,節點13,節點27,節點50
,刪除任意一個節點之後 剩下的還是滿足一棵二叉搜尋樹
第二種情況:node只有一個孩子 這種情況又分兩種
node節點有一個左孩子
node節點有一個右孩子
上面兩種情況其實不影響,比如圖中的節點10,節點45
,分別有一個左孩子和一個右孩子。 也好辦,節點10刪除後,它的左孩子節點5,放在節點10的位置 同理知,節點45刪除後,它的右孩子節點50,放在節點45的位置 這樣一來,剩下的節點還是一棵二叉搜尋樹
第三種情況:node有兩個孩子 還是上圖為準,以節點17
為例,節點17
有左右兩個孩子,分別是10,19 要刪除節點17
,怎麼辦呢? 或者說節點17
刪除 後,哪個節點應該放在節點17
的位置上呢?
我們節點17
滿足兩個性質 :
17大於它的左孩子10
17小於它的右孩子19
那麼我們找到一個這樣的節點,只要滿足上面這兩條性質,不就是可以了嗎。 so easey
我們就來先找一個大於10而且小於19的節點
大於 10 的節點,只要在 17 的右子樹 也就是以 19 為根節點的樹中找不就行了嗎 因為17的右子樹中所有的節點都比 17 大
小於 19 的節點,只要在以 19 為根的樹中找左孩子不就得了嗎 經過上面的分析,這樣的節點就是 13 啊,將17刪除 ,把13放到17的位置 ,如圖
其實,把10放到17的位置也是可以的。如下圖
10和13兩個節點都滿足條件,所以我們可以得出結論
刪除一個有兩個孩子節點,可以找這個節點左子樹中的最大節點,或者右子樹中的最小節點來放到當前位置
s 可以叫做 d 的後繼 s.right = deledeMin(d->right) s.left = d.left; 刪除 d, s 是新的子樹的根
翻譯成程式碼如下:
同過上面的分析,我們瞭解了二叉搜尋樹的性質,以及插入,查詢,查詢最大節點,查詢最小節點,刪除最大節點,刪除最小節點,以及最後分析出來刪除一個任意節點。
下面我們粘出完整程式碼 。如下
相關文章
1 折半查詢法瞭解二叉查詢樹之前,先來看看折半查詢法,也叫二分查詢法 在一個有序的整數陣列中(假如是從小到大排序的),如果查詢某個元素,返回元素的索引。如下:思想很簡單: 1 先找
2021-07-11 03:08:59
蘋果供應鏈的「內鬼」又立功了,以前關於iPhone 13的爆料都是工業渲染圖,雖然細節拉滿,但是不夠真實。就在我們都在猜測iPhone 13外觀的時候,一名國產配件廠商直接跳了出來,一甩手
2021-07-11 03:08:49
2020年12月16日,華為釋出了鴻蒙OS 2.0開發者移動測試版,同日,華為還開啟了華為P40、Mate 30、MatePad Pro裝置在中國的鴻蒙2.0測試招募。#華為鴻蒙# 測試版的初步實踐表明,華為
2021-07-11 03:08:43
在上汽董事長髮表了靈魂之說後,長城也宣佈與高通合作研發自動駕駛技術,它們均未有選擇號稱自動駕駛技術領先的國內企業華為,引發巨大爭議;然而近日外資品牌大眾卻宣佈獲取華為的
2021-07-11 03:08:32
過去買U盤,買個8G、16G就夠用。如今大資料時代,檔案資料是越來越大。像我平時拍攝個4K視訊,動不動就幾十G的資料量,我那個16GB U盤扛不住啊。平時又需要在公司與家裡之間拷貝資
2021-07-11 03:08:16
#月亮#都是月亮惹的禍?月相對睡眠週期的影響月亮,常被古今中外不少文化認定是造成一些自然災害的罪魁禍首。除了災害,自古人們也相信,月亮會影響人的情緒與行為。而發表在Scienc
2021-07-11 03:08:01