二叉搜尋樹BST

2022-08-05 01:57:15 字數 3291 閱讀 7059

二叉搜尋樹(binary search tree)它要麼是一棵空樹,要麼是一棵具有下列性質的二叉樹:若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 它的左,右子樹也分別為二叉搜尋樹

二叉搜尋樹上的每乙個結點都維護四個值,乙個是它本身的權值data,有siz表示當前點為根的子樹大小,ls記錄左兒子的編號,rs記錄右兒子的編號

1. 插入節點(insert)

插入節點的時候從根節點出發

(1) 如果當前節點為空,則將data賦為我們要插入的節點,siz初始化為1,再將其父親連向他(這裡我們要注意,二叉搜尋樹,是不記錄父節點的,為了能使其父親連向他,我們每次呼叫insert函式的時候我們傳入其父親指向其子節點的位址,而我們要使其父親指向它,就是將該位址上的值改為新節點的編號)

(2) 如果要插入的節點比我們當前的節點小,就向該節點的左子樹前進,同時,將該節點的siz加1(因為要插入的節點一定是插入到該節點的子樹中去了)

(3) 如果要插入的節點比我們當前的節點大等於我們當前的節點,就向該節點的右子樹前進,同時,將該節點的siz加1(因為要插入的節點一定是插入到該節點的子樹中去了)

是不是很容易呀,實現如下:

void insert(int &now,int

v) ++siz[now];

if(data[now]<=v) insert(rs[now],v);

else

insert(ls[now],v);

}

2. 刪除節點(del)

其實刪除操作非常奇怪,我們不可以直接刪除乙個有兩個子節點的節點,我們從根節點出發

(1) 如果當前節點為空就返回

(2) 如果要插入的節點比我們當前的節點小,就向該節點的左子樹前進,同時,將該節點的siz加1(因為要插入的節點一定是插入到該節點的子樹中去了)

(3) 如果要插入的節點比我們當前的節點大,就向該節點的右子樹前進,同時,將該節點的siz加1(因為要插入的節點一定是插入到該節點的子樹中去了)

(4) 如果要插入的節點等於我們當前的節點

a) 如果該點只有乙個兒子,就直接將該點的父親連向該點的兒子,連線方法如上

b) 不然,我們就找到比該點大的最小點,將兩點交換,再刪除比該點大的最小點

是不是很容易呀,實現如下:

void del(int &now,int

v) }

else

if(data[now]<=v) del(rs[now],v);

else

del(ls[now],v);

}

3.查詢某數排名(rank)

我們從根節點出發

(1) 如果當前節點為空就返回1

(2) 如果要插入的節點比我們當前的節點小,就向該節點的左子樹繼續查詢

(3) 如果要插入的節點比我們當前的節點大,就向該節點的右子樹繼續查詢,同時將查詢得到的值+siz+1後返回

其實很容易寫錯,實現如下:

int rank(int &now,int

v)

4. 查詢第k大的數(kth)

我們從根節點出發

(1) 如果當前節點為空就返回-1(找不到)

(2) 如果要查的排名等於siz[ls[now]]+1,就返回該節點

(3) 如果要插入的節點比我們當前的節點小,就向該節點的左子樹繼續查詢

(4) 如果要插入的節點比我們當前的節點大,就向該節點的右子樹繼續查詢排名為k-siz-1的數

其實很容易寫錯,實現如下:

int kth(int &now,int

v)

5. 求某數的前驅(前驅定義為小於該數,且最大的數)(pred)

我們從根節點出發

(1) 如果當前節點為空就返回-0x3f3f3f3f

(2) 如果要插入的節點比我們當前的節點小或等於我們當前的節點,就向該節點的左子樹繼續查詢

(3) 如果要插入的節點比我們當前的節點大,就向該節點的右子樹繼續查詢,並將查詢得到的值與該點取最大值返回

其實很容易寫錯,實現如下

int pred(int &now,int

v)

6. 求某數的後繼(後繼定義為大於該數,且最小的數)(succ)

我們從根節點出發

(1) 如果當前節點為空就返回0x3f3f3f3f

(2) 如果要插入的節點比我們當前的節點小,就向該節點的左子樹繼續查詢,並將查詢得到的值與該點取最小值返回

(3) 如果要插入的節點比我們當前的節點大或等於我們當前的節點,就向該節點的右子樹繼續查詢

其實很容易寫錯,實現如下:

int succ(int &now,int

v)

是不是很容易呀,完整**如下:

#include #include 

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

inline

intread()

const

int n=100100

;int tot(0),root(0

),siz[n],ls[n],rs[n],data[n],op,x,n;

void insert(int &now,int

v) ++siz[now];

if(data[now]<=v) insert(rs[now],v);

else

insert(ls[now],v);

}void del(int &now,int

v) }

else

if(data[now]<=v) del(rs[now],v);

else

del(ls[now],v);

}int rank(int &now,int

v)int kth(int &now,int

v)int pred(int &now,int

v)int succ(int &now,int

v)int

main()

return0;

}/**/

二叉搜尋樹BST

在二叉搜尋樹b中查詢x的過程為 1.若b是空樹,則搜尋失敗,否則 2.若x等於b的根結點的資料域之值,則查詢成功 否則 3.若x小於b的根結點的資料域之值,則搜尋左子樹 否則 4.查詢右子樹 指標parent指向proot的父節點,其初始呼叫值為null 若查詢成功,指標ptarget指向目標節點,...

二叉搜尋樹(BST)

二叉搜尋樹 bst bst 或者是一棵空樹,或者對於任何乙個結點,設其值為k,則該結點的左子樹的值小於k,右結點的值大於k。二叉搜尋樹按照中根遍歷將各個結點列印,將得到按照大到小的順序排列。bsg示意圖 二叉搜尋樹的效率在於檢索,將演算法複雜度從2 k減少到log n 檢索方式 從根結點開始,如果等...

BST二叉搜尋樹

深入學習理解bst include using namespace std typedef struct bitnodebitnode,bitree 二叉樹的插入操作 void insert bitnode root,int x 因為當對空樹插入時,相當於改變了樹的根節點的指向,因此需要用到指標或引...