二叉查詢樹BST總結

2021-07-15 22:57:22 字數 3102 閱讀 6224

adt bst

1.空樹

2.非空樹並且左子樹所有節點的鍵值均小於本節點的鍵值

右子樹所有的節點的鍵值均大於本節點的鍵值

該節點的左右子樹均為二叉查詢樹

t( n ) = t( n/2 ) + o( 1 ) 

t( n ) = t( n/4 ) + 2 o( 1 ) 

t( n ) = t( n/8 ) + 3 o( 1 ) 

… …[共 logn 次] 

… t( n ) = t( 1 ) + logn·o( 1 )

t( n ) = o(logn)

插入節點的核心在於查詢到當前的節點的父親節點,對於空樹來說,插入的節點直接充當根節點

對於非空樹來說,操作步驟如下:(c節點代表當前訪問到的的節點的位置,p節點代表帶插入的節點,n代表待插入節點的父節點)

1.c節點為空,那麼n即為c節點的父親節點,此時我們要進行大小比較少,如果p節點的鍵值比n節點的鍵值小,那麼p作為n的左孩子否則作為右孩子

2.否則,比較p節點的鍵值與c節點的鍵值

3.如果鍵值相同,說明使用者正在試圖插入乙個已經存在的節點,此時根據情況,我們可以丟擲異常或者我們提醒使用者

4.如果p節點的鍵值比c節點的鍵值要小,說明p節點應該存在於c節點的左子樹中,此時,n節點為c節點,我們將c轉移到左孩子上,跳轉到操作1

5.否則,跳轉到右孩子上,然後執行操作1

查詢節點的操作和插入節點的操作大致是相同的,複雜度都是logn:(k代表待查詢的鍵值,c代表當前的節點(初始為根節點))

1.如果k等於c的鍵值,說明該節點我們已經查詢到了,返回查詢到的位址就好

2.如果c節點為空,說明該節點查詢失敗,該節點不存在,返回null即可

3.否則,我們進行判斷,如果k的鍵值相對較小,說明待查詢的節點要麼不存在要麼就在左子樹中,我們將c跳轉到左子樹中,執行操作1

4.否則,說明待查詢的節點要麼不存在,要麼就存在在右子樹中,我們將c跳轉到右孩子中,執行操作1

從 bst 中刪除節點比插入節點難度更大。因為刪除乙個非葉子節點,就必須選擇其他節點來填補因刪除節點所造成的樹的斷裂。如果不選擇節點來填補這個斷裂,那麼就違背了 bst 的性質要求。

刪除節點演算法的第一步是定位要被刪除的節點,這可以使用前面介紹的查詢演算法,因此執行時間為 o(log­2n)。接著應該選擇合適的節點來代替刪除節點的位置,它共有三種情況需要考慮。

我們知道,在 bst 中,最小值的節點總是在最左邊,最大值的節點總是在最右邊。因此替換被刪除節點右子樹中最小的乙個節點,就保證了該節點一定大於被刪除節點左子樹的所有節點。同時,也保證它替代了被刪除節點的位置後,它的右子樹的所有節點值都大於它。因此這種選擇策略符合二叉查詢樹的性質。

和查詢、插入演算法類似,刪除演算法的執行時間也與 bst 的拓撲結構有關,最佳情況是 o(log­2n),而最壞情況是 o(n)。

#include"iostream"

#include"cstdio"

#include"cstring"

#include"cstdlib"

using namespace std;

typedef struct node

point;

class errorsame

; class bst

~bst()

void add(int);

void del(int);

point* find(int);

void clear(point*);

void preorder(point*);

void midorder(point*);

void aftorder(point*);

void rankorder();

point* returnroot()

private:

point* root;

int num;

};void bst::clear(point* p)

}void bst::add(int p)

else

if(w!=null) k=w;

}if(k->key>p)

else

num++;

} catch(errorsame e)

else

if(now==null)

else

z->left=k->right;

k->left=root->left;

k->right=root->right;

root=k;}}

free(help);

} else if(now->right==null)

else

else

if(father->left==now)

else

} }}

point* bst::find(int p)

} void bst::preorder(point* p)

}void bst::midorder(point* p)

}void bst::aftorder(point* p)

}void bst::rankorder()

for(int i=1;i<=tail-1;i++) printf("%d ",queue[i]->key);

}int main()

{ bst my;

my.add(1);

my.add(15);

my.add(7);

my.add(5);

my.add(11);

my.add(2);

my.add(9);

my.preorder(my.returnroot());

cout

1.二叉查詢樹在退化線性結構的時候,複雜度的計算目前尚且不熟練

2.二分法和二叉鍊錶的核心區別

3.為什麼說遍歷兒茶查詢樹的效率相對來說會低於線性結構的資料結構,是因為訪問點回溯的原因嗎

scale-out thinking的部落格

csdn論壇

遞推式的複雜度分析

tanglinux的部落格

二叉查詢樹 BST

當所有的靜態查詢結構新增和刪除乙個資料的時候,整個結構都需要重建。這對於常常需要在查詢過程中動態改變資料而言,是災難性的。因此人們就必須去尋找高效的動態查詢結構,我們在這討論乙個非常常用的動態查詢樹 二叉查詢樹。二叉查詢樹的特點 下面的圖就是兩棵二叉查詢樹,我們可以總結一下他的特點 1 若它的左子樹...

二叉查詢樹(BST)

二叉查詢樹,也稱為二叉排序樹,二叉搜尋樹。二叉查詢樹結合了鍊錶插入的靈活性和有序陣列查詢 二分查詢 的高效性。用二叉查詢樹實現有序符號表的api。public class bst,value 有序符號表的相關方法 public intsize private intsize node x publi...

二叉查詢樹BST

樹由node物件組成,每個物件有一對鍵值 兩條鏈結和乙個節點計數器n。每個node物件都是一棵含有n個節點的子樹的根節點,它的左鏈結指向一棵由小於該節點的所有鍵組成的二叉查詢樹,右鏈結指向一棵由大於該節點的所有鍵組成的二叉查詢樹。在bst類中,還應定義乙個node物件root,指向當前二叉樹的根節點...