演算法與資料結構之二叉搜尋樹

2021-10-10 12:52:29 字數 2735 閱讀 9275

搜尋樹與二叉搜尋樹

搜尋樹是一種可以進行插入、搜尋、刪除等操作的資料結構。它可以用作字典或者優先順序佇列。

二叉搜尋樹是最基本的搜尋樹。它的各個結點都有鍵值,並且滿足以下的條件:

設x是二叉搜尋樹中的結點,y是它的左子樹中的結點,那麼,y的鍵值≤x的鍵值。

根據這一特點,我們就能實現一棵二叉搜尋樹。

二叉搜尋樹的插入

根據上述的二叉搜尋樹的特徵,我們就能很方便的實現將元素插入到二叉搜尋樹中。

如果待插入結點的鍵值小於當前結點的鍵值,那麼就在左子樹中遞迴地執行上述操作,直至待插入結點被插入到二叉樹的乙個葉結點後面,成為新的葉結點。

這個插入演算法的時間複雜度為o(h),其中h是二叉樹的高。

二叉搜尋樹的搜尋

二叉搜尋樹的搜尋過程和插入過程相似,就是不斷比較關鍵字和當前結點的鍵值之間的關係,然後在相應的子樹中查詢。如果當前結點的鍵值等於關鍵字,那麼就是找到了。如果直到搜尋到葉結點也無法匹配到關鍵字,那麼就說明這個關鍵字不存在於這棵二叉搜尋樹之中。

二叉搜尋樹的刪除

這是乙個有難度的問題。

二叉搜尋樹的刪除需要在刪除結點後,仍然滿足二叉搜尋樹的結構。那怎麼辦呢?我們要刪除某個結點,那麼我們只需要把這個結點的左子樹中鍵值最大的結點的值複製到當前結點,然後刪除被複製的那個結點。或者刪除右子樹中鍵值最小的結點,並把鍵值複製到當前結點。

感覺有點繞,那麼就把上面這棵二叉搜尋樹當個例子來講。

情況1:

我們要刪除鍵值為35的結點,那麼只需要把30號結點的右子結點指向空結點,然後把鍵值為35的結點free掉就可以了。

情況2:

我們要刪除鍵值為55的結點,那麼我們在55的右子樹中尋找鍵值最大的結點,也就是70結點。接著把55結點的鍵值賦值為70,最後把最下端的70結點free掉就可以了。然後會發現,刪除後仍然滿足二叉搜尋樹的結構。

情況3:

對於下面這棵二叉搜尋樹:

我們要刪除40號結點,這個結點沒有右子樹。那怎麼辦呢?分析可以知道,我們只需要把45結點和30結點連線起來。然後把40結點free掉。我在這裡就要實名點名一下《挑戰程式設計競賽2》中的方法。書上講的是向上查詢第乙個非空的且當前結點不是父節點的右子結點的結點。那個方法真是把人都給繞暈了。其實分析就可以發現,在當前結點的右子樹不存在的時候,只需要把當前結點的左子樹接到當前結點的父節點的左邊,然後把當前節點free掉就好了。這就很簡單地解決了,並且**量比書上的少了不少。

有圖有真相,下面是書上的程式的評測結果

然後我的方法:

**量減少了,執行時間差不多。而且真的好理解很多!

**實現

題目位於

#include#include#include#includeusing namespace std;

struct node

;node *root;

node *nil;

//插入元素到二叉樹裡面

void ins(int k)

else this_node = this_node->right;

}insert_node->parent = last_node;//把節點接在正確的位置

資料結構與演算法之二叉搜尋樹

看到有個傢伙寫的很好 二叉查詢樹 二 之 c 的實現 二叉搜尋樹的定義 一棵二叉樹,可能為空 一棵非空的二叉搜尋樹滿足以下特徵 每個元素有乙個關鍵字,並且任意兩個元素的關鍵字都不同,因此,所有的關鍵字都是唯一的。在根節點的左子樹中,元素的關鍵字 如果有的話 都小於根節點的關鍵字。在根節點的右子樹中,...

資料結構之二叉搜尋樹

什麼是二叉搜尋樹呢?它與別的資料結構相比其優勢又是什麼呢?一顆二叉搜尋樹就是以一顆二叉樹來組織和儲存資料的,如圖所示 圖a是包含6個節點 高度為2的二叉樹,圖b是包含相同關鍵字 高度為4的低效二叉樹 對比博文前面所介紹的鍊錶,二叉樹也是可以用結構體來實現,只不過每個節點裡面不僅要儲存資料本身的關鍵字...

資料結構與演算法之二叉樹

樹同時具有鍊錶和陣列的優點,關於樹的術語有 根 樹頂端的節點 葉子節點 沒有子節點的節點 樹那個節點所對應的資料結構 節點物件類,包含資料 public class node 將資料插到樹中 public void inser int id,double dd public boolean dele...