二叉查詢樹(c ) 實用的資料結構

2022-05-11 16:02:51 字數 3431 閱讀 3598

二叉查詢樹又名二叉排序樹、二叉搜尋樹、bst(binary search tree)。首先知道它的基礎資料結構。

它是一顆二叉樹(帶權),通常會用結構體實現(陣列或者指標——個人比較喜歡用陣列,之後的**也是用陣列來實現的)。

struct

nodetree[size];

int tot; //

記錄共有幾個節點

int root; //

記錄根節點

不過它有乙個性質:對於任意乙個非葉子節點,它的左子樹所有的節點的權值都《他的權值,它的右子樹所有的節點的權值》它的權值。

其次它可以實現以下功能:

• 建立關鍵碼為x的節點

• 檢索

• 插入關鍵碼為x的節點

• 求關鍵碼為x的節點的前驅

• 求關鍵碼為x的節點的後繼

• 刪除關鍵碼為x的節點

update:求排名和排名的關鍵碼

• 求關鍵碼為x的節點的排名

• 求排名為x的節點的關鍵碼

1,建立關鍵碼

這個沒什麼好講的吧。

//

插入乙個權值為v的新節點

int new(int

v)

2,bst的檢索

在bst中檢索是否存在權值為v的節點。

設變數p等於根節點root,執行以下過程:

1.若p的權值等於v,則已經找到

2.若p的權值大於v

a.若p的左子節點為空,則說明不存在v

b.若p的左子節點不空,在p的左子樹中遞迴進行檢索

3.若p的權值小於v

a.若p的右子節點為空,則說明不存在v

b.若p的右子節點不空,在p的右子樹中遞迴進行檢索

//

檢索關鍵碼為v的編號

int find(int p, int

v)

3,bst的插入

插入其實跟檢索差不多,只不過找的合適的位置後要把元素插入進去。

用乙個引用記錄其父節點的lson或rson值,這樣就可以輕鬆插入了。

//

更新節點資訊

void up(int

p) //

插入乙個關鍵碼為v的數

void insert(int &p, int

v)

if (v == bst[p].val) bst[p].cnt++;//

之前已經有v這個數了,直接次數+1

if (v > bst[p].val) insert(bst[p].ron, v);//

比他大,在他的右子樹里插

else insert(bst[p].lson, v);//

比他小,在他的左子樹里插

up(p);//

需要更新p的資訊(這裡是子樹大小)

}

up和線段樹類似,因為改變了p的兒子的資訊所以p的資訊肯定也要更改。

4,bst的後繼

首先檢索v,然後開始分類討論:

設v的節點編號為p。

i p有右子樹,則它的後繼一定在它的右子樹中否則它的右子樹將不是「它的右子樹」。

而且一定是它右孩子後一直往左孩子找。

ii 若p沒有右子樹,則它的後繼就是它的直系祖先中 > 它且最小的乙個(在檢索的時候記錄)

//

找關鍵碼為v的後繼

int next(int

v)

break

; }

if (bst[p].val > v && (ret == -1 || bst[p].val < bst[ret].val)) ret = p, p = bst[p].lson;//

檢索時記錄

else p =bst[p].rson;

}return

ret;

//返回字尾的節點編號,若沒有返回-1(如在2,3,4中找5的字尾)

}

5,bst找前驅

更後繼差不多,不過是左子樹一直往右走,紀錄時也是《它最大的乙個。

//

找關鍵碼為v的前驅

int pre(int

v)

break

; }

if (bst[p].val < v && (ret == -1 || bst[p].val > bst[ret].val)) ret = p, p = bst[p].rson;//

檢索時記錄

else p =bst[p].lson;

}return

ret;

//返回前驅的節點編號,若沒有返回-1(如在2,3,4中找1的前驅)

}

6,bst中刪除節點

首先也是先檢索它得到節點p

若v出現的大於1,那麼直接cnt--即可。

若p的子節點個數小於2,則直接刪除p,並令p的子節點代替p的位置,與p 的父節點相連。

若p既有左子樹又有右子樹,則在bst中求出v的後繼節點next。

因為next沒有左子樹(想想為什麼?),所以可以直接刪除next,並令next的右子樹代替next的位置。

最後, 再讓next節點代替p節點,刪除p即可。

void del(int &p, int

v) else

if (!bst[p].rson) else

}up(p);

return

; }

if (bst[p].val else

del(bst[p].lson, v);

up(p);

}

update:

7,bst查詢排名

我們用迴圈的方式來求

對於當前節點p開始分類討論

(1)valp=v,ret+=p左子樹大小並退出迴圈

(2)valp

p及其左子樹均排在v前面,ret+=cntp+p左子樹的大小,跳p

(3)valp>v,此時ret並不能增加,直接跳p

//

查詢v的排名

int rank(int

v)

if (v >bst[p].val)

else

}return ret + 1

;}

8,bst根據排名查詢數

有點類似主席樹,時間不早了,這就不講了

//

查詢排名為k的數

int kth(int

k) k -=bst[p].cnt;

p =bst[p].rson;}}

return

ret;

}

update1:3-8

講真bst沒什麼n用,但它是學習平衡樹的基礎。

(資料結構)二叉查詢樹

樹,是一種資料結構。它是由n個有限節點組成乙個具有層次關係的集合。特點 樹的基本術語 節點的度 節點擁有的子樹的數目。葉子 度為零的節點。分支節點 度不為零的節點。樹的度 樹中節點的最大的度。層次 根節點的層次為1,其餘節點的層次等於該節點的雙親的層次加1。樹的高度 樹中節點的最大層次。無序樹 如果...

資料結構 二叉查詢樹

使二叉樹成為二叉查詢樹的性質是,對於樹中的每個節點x,它的左子樹中所有關鍵字值小於x的關鍵字值,而它的右子樹中所有關鍵字值大於x的關鍵字值。這意味著,該樹所有的元素以某種統一的方式排序。二叉查詢樹是一棵特殊的二叉樹,二叉查詢樹中節點的結構與二叉樹種節點的結構相同,關鍵在於可以在二叉查詢樹上可以執行的...

資料結構 樹 二叉查詢樹

wiki 首先是名稱 二叉查詢樹英文叫binary search tree,這個在很多演算法題目中很常見所以要記住,特別是英文題目中。也叫做二叉排序樹,二叉搜尋樹等等。具體的定義比較官方,用自己的話說,首先它肯定是二叉樹,其次,當前節點的左子葉元素值比當前節點小,右子葉元素值比當前節點大,所以節點均...