資料結構之二叉排序樹

2022-08-18 00:21:07 字數 3588 閱讀 9901

1.什麼是二叉排序樹?

二叉排序樹(binary sort tree)又稱二叉查詢樹(binary search tree),亦稱二叉搜尋樹。 它或者是一棵空樹;或者是具有下列性質的二叉樹:

(1)若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;

(2)若右子樹不空,則右子樹上所有結點的值均大於或等於它的根結點的值;

(3)左、右子樹也分別為二叉排序樹;

2.如何查詢?

步驟:

二叉樹若根結點的關鍵字

值等於查詢的關鍵字,成功。

否則,若小於根結點的關鍵字

值,遞迴

查左子樹。

若大於根結點的關鍵字

值,遞迴

查右子樹。

若子樹為空,查詢不成功。

平均情況分析(在成功查詢兩種的情況下):

在一般情況下,設 p(n,i)為它的左子樹的結點個數為 i 時的平均查詢長度。

如圖的結點個數為 n = 6 且 i = 3; 則 p(n,i)= p(6, 3) = [ 1+ ( p(3) + 1) * 3 + ( p(2) + 1) * 2 ] / 6= [ 1+ ( 5/3 + 1) * 3 + ( 3/2 + 1) * 2 ] / 6

注意:這裡 p(3)、p(2) 是具有 3 個結點、2 個結點的二叉分類樹的平均查詢長度。 在一般情況,p(i)為具有 i 個結點二叉分類樹的平均查詢長度。

p(3) = (1+2+2)/ 3 = 5/3

p(2) = (1+2)/ 2 = 3/2∴ p(n,i)= [ 1+ ( p(i) + 1) * i + ( p(n-i-1) + 1) * (n-i-1) ] / n

∴ p(n)=

p(n,i)/ n <= 2(1+i/n)lnn

因為 2(1+i/n)lnn≈1.38logn 故p(n)=o(logn)

3.刪除節點:

在二叉排序樹刪去乙個結點,分三種情況討論:

若*p結點為葉子結點,即pl(左子樹)和pr(右子樹)均為空樹。由於刪去葉子結點不破壞整棵樹的結構,則只需修改其雙親結點的指標即可。

若*p結點只有左子樹pl或右子樹pr,此時只要令pl或pr直接成為其雙親結點*f的左子樹(當*p是左子樹)或右子樹(當*p是右子樹)即可,作此修改也不破壞二叉排序樹的特性。

若*p結點的左子樹和右子樹均不空。在刪去*p之後,為保持其它元素之間的相對位置不變,可按中序遍歷保持有序進行調整,可以有兩種做法:

其一是令*p的左子樹為*f的左/右(依*p是*f的左子樹還是右子樹而定)子樹,*s為*p左子樹的最右下的結點,而*p的右子樹為*s的右子樹;

其二是令*p的直接前驅(或直接後繼)替代*p,然後再從二叉排序樹中刪去它的直接前驅(或直接後繼)-即讓*f的左子樹(如果有的話)成為*p左子樹的最左下結點(如果有的話),再讓*f成為*p的左右結點的父結點。

4.插入節點:

首先執行查詢演算法,找出被插結點的父親結點。

判斷被插結點是其父親結點的左、右兒子。將被插結點作為葉子結點

插入。若二叉樹

為空。則首先單獨生成根結點。

注意:新插入的結點總是葉子結點

。5.效能分析:

每個結點的c(i)為該結點的層次數。最壞情況下,當先後插入的關鍵字有序時,構成的二叉排序樹蛻變為單支樹,樹的深度為,其平均查詢長度為(n+1)/2(和順序查詢相同),最好的情況是二叉排序樹的形態和折半查詢的判定樹相同,其平均查詢長度和log 2 (n)成正比

#include #include 

#include

#include

using

namespace

std;

typedef

struct bitnode//

二叉排序樹的儲存結構

*bitree;

void visit(bitree &p)//

遍歷void inorder(bitree &p)//

中序遍歷,可檢驗二叉排序樹是否正確,若正確,中序遍歷是乙個單調不減的序列

}bool eq(int a,int b)//

判斷當前節點與插入節點是否相等

bool lt(int a,int b)//

判斷當前節點是否與插入節點存在大小關係

bool rt(int a,int b)//

判斷當前節點是否與插入節點存在大小關係

//#define eq(a,b) ((a) == (b))

//#define lt(a,b) ((a) < (b))

//#define lq(a,b) ((a) <= (b))

//在根指標t所指排序二叉樹中遞迴地查詢某關鍵字等於key的資料元素,若查詢成功,則指標p只想該資料元素節點,並返回true;否則指標p指向查詢路徑上訪問的最後乙個節點並返回false,指標f指向t的雙親,其初始呼叫值為null

bool searchbst(bitree t,int key,bitree f,bitree *p)

else

if(eq(key,t->data))

else

if(lt(key,t->data))

else}//

當排序二叉樹t中不存在關鍵字等於key的元素時,插入e並返回true,否則返回false。

void insertbst(bitree *t,int

e)

else

if(lt(e,p->data))

else

return

; }

//樹中已經有關鍵字相同的節點,不再插入

else

}void delete(bitree &p)

else

if(p->lift==null)

else

p->data=s->data;//

s指向被刪除節點的「前驅」(將被刪除節點的前驅的值取代被刪除節點的值)

if(q!=p)

q->right=s->right;//

重接q的右子樹

else

q->right=s->lift;//

重接q的左子樹

free(s);

}}void deletebst(bitree &t,int

key)

else

if(lt(key,t->data))

else

}}int search(bitree t,int

key)

else

if(lt(t->data,key))//

<

else

if(rt(t->data,key))//

>

}return0;

}int

main()

cin>>j;

if(search(p,j)!=0)cout<

yes

"else cout<

<

}return0;

}

資料結構之二叉排序樹

二叉排序樹或者是一棵空樹,或者是具有下列性質的二叉樹 1 若左子樹不空,則左子樹上所有節點的值均小於它的根節點的值 2 若右子樹不空,則右子樹上所有節點的值均大於它的根節點的值 3 左 右子樹也分別為二叉排序樹 4 沒有鍵值相等的節點。以下只建立並先序列印出二叉排序樹 include include...

資料結構之二叉排序樹

二叉排序樹 bst binary sort search tree 對於二叉排序樹的任何乙個非葉子節點,要求左子節點的值比當前節點的值小,右子節點的值比當前節點的值大。特別說明 如果有相同的值,可以將該節點放在左子節點或右子節點 比如針對前面的資料 7,3,10,12,5,1,9 對應的二叉排序樹為...

資料結構之二叉排序樹

別名 二叉搜素樹,二叉查詢樹 線性結構的缺點 順序儲存 不排序 查詢困難,只能通過線性查詢乙個乙個找 排序 刪除和插入操作困難 鏈式結構 無論排序還是不排序,查詢都十分麻煩 注 二叉排序樹 bst 可以解決上述的問題 對於乙個二叉樹中的任意乙個非葉子節點,要求左子節點比當前節點小,右子節點比當前節點...