二叉排序樹(Binary Sort Tree)或者是一棵空樹;或者是具有下列性質(zhì)的二叉樹:(1)若左子樹不空,則左子樹上所有結(jié)點(diǎn)的值均小于它的根結(jié)點(diǎn)的值;(2)若右子樹不空,則右子樹上所有結(jié)點(diǎn)的值均大于它的根結(jié)點(diǎn)的值;(3)左、右子樹也分別為二叉排序樹;
中文名稱 | 二叉排序樹 | 外文名稱 | Binary Sort Tree? |
---|---|---|---|
別 稱 | 二叉查找樹、二叉搜索樹? | 別稱外文名 | Binary Search Tree |
若根結(jié)點(diǎn)的關(guān)鍵字值等于查找的關(guān)鍵字,成功。
否則,若小于根結(jié)點(diǎn)的關(guān)鍵字值,遞歸查左子樹。
若大于根結(jié)點(diǎn)的關(guān)鍵字值,遞歸查右子樹。
若子樹為空,查找不成功。
插入算法:
首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。
判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左、右兒子。將被插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。
若二叉樹為空。則首先單獨(dú)生成根結(jié)點(diǎn)。
注意:新插入的結(jié)點(diǎn)總是葉子結(jié)點(diǎn)。
void InsertBST(t,key)
//在二叉排序樹中插入查找關(guān)鍵字key
{
if(t==NULL){
t=new BiTree;
t->lchild=t->rchild=NULL;
t->data=key;
return; }
if(keydata ) InsertBST(t->lchild,key);
else InsertBST (t->rchild, key );
}
void CreateBiTree(tree,d【 】,n)
//n個(gè)數(shù)據(jù)在數(shù)組d中,tree為二叉排序樹根
{tree=NULL;
for(i=0;i InsertBST(tree,d);
}
擊【分部整理】,會(huì)顯示下方窗口,如圖一: 鉤選分部規(guī)則后點(diǎn)擊“執(zhí)行分部整理”即可。 點(diǎn)擊【分部整理】,會(huì)顯示下方窗口,如圖二: 點(diǎn)擊“執(zhí)行子目排序”即可
使用08定額,建筑與裝飾最好分開(分兩個(gè)預(yù)算)做,就不會(huì)出現(xiàn)借用定額的代號(hào)了,直接點(diǎn)分部整理即可排序,如果不想分為兩個(gè)預(yù)算,裝飾部分可以按鼠標(biāo)右鍵插入分部輸入編號(hào)、分部名稱,然后將該分部的子目用上下移...
二叉樹在計(jì)算機(jī)科學(xué)中,二叉樹是每個(gè)結(jié)點(diǎn)最多有兩個(gè)子樹的有序樹。通常子樹的根被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹常被用作二叉查找樹和二叉堆。二叉...
格式:pdf
大?。?span id="ffzj2h0" class="single-tag-height">71KB
頁(yè)數(shù): 4頁(yè)
評(píng)分: 4.8
分層模式在軟件開發(fā)中有著廣泛的應(yīng)用,必然使各層之間產(chǎn)生頻繁的數(shù)據(jù)交互,從而導(dǎo)致軟件性能大大下降。針對(duì)上述問(wèn)題,本文提出一種基于有序二叉樹的變量池的解決方案,軟件的配置信息以及各層之間的交互數(shù)據(jù)保存在變量池中,對(duì)變量的所有操作都基于變量池,通過(guò)變量池的使用,既方便了各層之間數(shù)據(jù)交互,也簡(jiǎn)化了各層之間的接口設(shè)計(jì)?;谠摲桨?本文最后實(shí)現(xiàn)了一個(gè)銀行自助終端系統(tǒng)。
格式:pdf
大?。?span id="zwt5hdy" class="single-tag-height">71KB
頁(yè)數(shù): 10頁(yè)
評(píng)分: 4.4
第 8 章 排序 1.選擇題 ( 1)從未排序序列中依次取出元素與已排序序列中的元素進(jìn)行比較, 將其放入已排序序 列的正確位置上的方法,這種排序方法稱為( )。 A.歸并排序 B.冒泡排序 C.插入排序 D.選擇排序 答案: C ( 2)從未排序序列中挑選元素,并將其依次放入已排序序列(初始時(shí)為空)的一端的方 法,稱為( )。 A.歸并排序 B.冒泡排序 C.插入排序 D.選擇排序 答案: D ( 3)對(duì) n 個(gè)不同的關(guān)鍵字由小到大進(jìn)行冒泡排序,在下列( )情況下比較的次數(shù)最 多。 A.從小到大排列好的 B.從大到小排列好的 C.元素?zé)o序 D.元素基本有序 答案: B 解釋:對(duì)關(guān)鍵字進(jìn)行冒泡排序,關(guān)鍵字逆序時(shí)比較次數(shù)最多。 ( 4)對(duì) n 個(gè)不同的排序碼進(jìn)行冒泡排序, 在元素?zé)o序的情況下比較的次數(shù)最多為 ( )。 A. n+1 B. n C. n-1 D. n(n-1)/2 答案:
1.二叉排序樹的概念:
二叉排序樹是一種動(dòng)態(tài)樹表。
二叉排序樹的定義:二叉排序樹或者是一棵空樹,
或者是一棵具有如下性質(zhì)的二叉樹:
⑴ 若它的左子樹非空,則左子樹上所有結(jié)點(diǎn)的值均小于根結(jié)點(diǎn)的值;
⑵ 若它的右子樹非空,則右子樹上所有結(jié)點(diǎn)的值均大于根結(jié)點(diǎn)的值;
⑶ 左、右子樹本身又各是一棵二叉排序樹。二叉排序樹的性質(zhì): 按中序遍歷二叉排序樹,所得到的中序遍歷序列是一個(gè)遞增有序序列。
2.二叉排序樹的插入:
在二叉排序樹中插入新結(jié)點(diǎn),要保證插入后的二叉樹仍符合二叉排序樹的定義。
插入過(guò)程:若二叉排序樹為空,則待插入結(jié)點(diǎn)*S作為根結(jié)點(diǎn)插入到空樹中;
當(dāng)非空時(shí),將待插結(jié)點(diǎn)關(guān)鍵字S->key和樹根關(guān)鍵字t->key進(jìn)行比較,
若s->key = t->key,則無(wú)須插入,若s->key< t->key,則插入到根的左子樹中,
若s->key> t->key,則插入到根的右子樹中。而子樹中的插入過(guò)程和在樹中的插入過(guò)程相同,
如此進(jìn)行下去,直到把結(jié)點(diǎn)*s作為一個(gè)新的樹葉插入到二叉排序樹中,或者直到發(fā)現(xiàn)樹已有相同關(guān)鍵字的結(jié)點(diǎn)為止。
3. 二叉排序樹生成:
從空的二叉排序樹開始,經(jīng)過(guò)一系列的查找插入操作以后,生成了一棵二叉排序樹。
說(shuō)明:
① 每次插入的新結(jié)點(diǎn)都是二叉排序樹上新的葉子結(jié)點(diǎn)。
② 由不同順序的關(guān)鍵字序列,會(huì)得到不同二叉排序樹。
③ 對(duì)于一個(gè)任意的關(guān)鍵字序列構(gòu)造一棵二叉排序樹,其實(shí)質(zhì)上對(duì)關(guān)鍵字進(jìn)行排序。
4.二叉排序樹查找的程序?qū)崿F(xiàn):
5. 二叉排序樹的刪除:
假設(shè)被刪結(jié)點(diǎn)是*p,其雙親是*f,不失一般性,設(shè)*p是*f的左孩子,下面分三種情況討論:
⑴ 若結(jié)點(diǎn)*p是葉子結(jié)點(diǎn),則只需修改其雙親結(jié)點(diǎn)*f的指針即可。
⑵ 若結(jié)點(diǎn)*p只有左子樹PL或者只有右子樹PR,則只要使PL或PR 成為其雙親結(jié)點(diǎn)的左子樹即可。
⑶ 若結(jié)點(diǎn)*p的左、右子樹均非空,先找到*p的中序前趨結(jié)點(diǎn)*s(注意*s是*p的左子樹中的最右下的結(jié)點(diǎn),它的右鏈域?yàn)榭眨?,然后有兩種做法:
① 令*p的左子樹直接鏈到*p的雙親結(jié)點(diǎn)*f的左鏈上,而*p的右子樹鏈到*p的中序前趨結(jié)點(diǎn)*s的右鏈上。
② 以*p的中序前趨結(jié)點(diǎn)*s代替*p(即把*s的數(shù)據(jù)復(fù)制到*p中),將*s的左子樹鏈到*s的雙親結(jié)點(diǎn)*q的左(或右)鏈上。
6. 刪除算法演示 :
7. 二叉排序樹的查找:
在二叉排序樹中進(jìn)行查找的過(guò)程和二分查找類似,也是一個(gè)逐步縮小查找范圍的過(guò)程。若查找成功,則是走了一條從根結(jié)點(diǎn)到待查結(jié)點(diǎn)的路徑;若查找失敗,則是走了一條根結(jié)點(diǎn)到某個(gè)葉子結(jié)點(diǎn)的路徑。因此,查找過(guò)程中和關(guān)鍵字比較的次數(shù)不超過(guò)樹的深度。
由于含有n個(gè)結(jié)點(diǎn)的二叉排序樹不唯一,形態(tài)和深度可能不同。故含有n個(gè)結(jié)點(diǎn)的二叉排序樹的平均查找長(zhǎng)度和樹的形態(tài)有關(guān)。
最好的情況是: 二叉排序樹和二叉判定樹形態(tài)相同。
最壞的情況是: 二叉排序樹為單支樹,這時(shí)的平均查找長(zhǎng)度和順序查找時(shí)相同。
最壞情況示例
就平均性能而言,
二叉排序樹上的查找和二分查找相差不大,并且二叉排序樹上的插入和刪除結(jié)點(diǎn)十分方便,無(wú)須大量移動(dòng)結(jié)點(diǎn)。
二叉排序樹查找
二叉排序樹(Binary Sort Tree:BST)
1、二叉排序樹的定義
二叉排序樹(Binary Sort Tree)又稱二叉查找(搜索)樹(Binary Search Tree)。其定義為:二叉排序樹或者是空樹,或者是滿足如下性質(zhì)的二叉樹:
①若它的左子樹非空,則左子樹上所有結(jié)點(diǎn)的值均小于根結(jié)點(diǎn)的值;
②若它的右子樹非空,則右子樹上所有結(jié)點(diǎn)的值均大于根結(jié)點(diǎn)的值;
③左、右子樹本身又各是一棵二叉排序樹。
上述性質(zhì)簡(jiǎn)稱二叉排序樹性質(zhì)(BST性質(zhì)),故二叉排序樹實(shí)際上是滿足BST性質(zhì)的二叉樹。
2、二叉排序樹的特點(diǎn)
由BST性質(zhì)可得:
(1) 二叉排序樹中任一結(jié)點(diǎn)x,其左(右)子樹中任一結(jié)點(diǎn)y(若存在)的關(guān)鍵字必小(大)于x的關(guān)鍵字。
(2) 二叉排序樹中,各結(jié)點(diǎn)關(guān)鍵字是惟一的。
注意:
實(shí)際應(yīng)用中,不能保證被查找的數(shù)據(jù)集中各元素的關(guān)鍵字互不相同,所以可將二叉排序樹定義中BST性質(zhì)(1)里的"小于"改為"小于等于",或?qū)ST性質(zhì)(2)里的"大于"改為"大于等于",甚至可同時(shí)修改這兩個(gè)性質(zhì)。
(3) 按中序遍歷該樹所得到的中序序列是一個(gè)遞增有序序列。
【例】下圖所示的兩棵樹均是二叉排序樹,它們的中序序列均為有序序列:2,3,4,5,7,8。
3、二叉排序樹的存儲(chǔ)結(jié)構(gòu)
typedef int KeyType; //假定關(guān)鍵字類型為整數(shù)
typedef struct node { //結(jié)點(diǎn)類型
KeyType key; //關(guān)鍵字項(xiàng)
InfoType otherinfo; //其它數(shù)據(jù)域,InfoType視應(yīng)用情況而定,下面不處理它
struct node *lchild,*rchild,*parent; //左右孩子指針
} BSTNode;
typedef BSTNode *BSTree; //BSTree是二叉排序樹的類型
二叉排序樹的基本操作(pascal):
1.中序遍歷所有元素
procedure tree_walk(x:longint);
begin
if x<>0 then
begin
tree_walk(left[x]);
write(key[x]);
tree_walk(right[x]);
end;
2.查找給定的元素
function tree_search(x,k:longint):longint;
begin
if (x=0) or (k=key[x]) then exit(x);
if k end; 非遞歸版本 function tree_search(x,k:longint):longint; begin while (x<>0) and (k<>key[x]) do begin if k end; exit(x); end; 3.查找最小元素 function tree_minimum(x:longint):longint; begin while left[x]<>0 do x:=left[x]; exit(x); end; 查找最大元素 function tree_maximum(x:longint):longint; begin while right[x]<>0 do x:=right[x]; exit(x); end; 4. 求后繼 function tree_successor(x:longint):longint; var y:longint; begin if right[x]<>0 then exit(tree_minimum(right[x]));//若右子樹不空,則返回右子樹中的最小值 y:=p[x];//若右子樹為空,則后繼y為x的最低祖先節(jié)點(diǎn),且y的左兒子也是x的祖先 while (y<>0) and (x=right[y]) do begin x:=y; y:=p[y]; end; exit(y);//注意,若y為0,則x無(wú)后繼 end; //注意,函數(shù)返回值為節(jié)點(diǎn)編號(hào),并不是節(jié)點(diǎn)本身的值 5.插入 procedure tree_insert(z:longint);//注意z為節(jié)點(diǎn)編號(hào),并非樹中的值 var x,y:longint; begin y:=0; x:=root; while x<>0 do//查找z的父節(jié)點(diǎn),y記錄 begin y:=x; if key[z] end; p[x]:=y; if y=0 then root:=z//若z為根節(jié)點(diǎn) else begin if key[z] end; end; 6.刪除 刪除操作是最麻煩的,分3種情況: (1)若z無(wú)子樹,則就刪除z節(jié)點(diǎn),更新p[z]的值為空 (2)若z有一個(gè)子樹,刪除z節(jié)點(diǎn),更新p[z]的值為z的兒子節(jié)點(diǎn),更新left[p[z]] 或 right[p[z]] (3)若z有兩棵子樹,先找到z的后繼y(后繼節(jié)點(diǎn)無(wú)左子樹,可證),刪除y節(jié)點(diǎn),更新p[y]與left[p[y]] 或 right[p[y]],最后用節(jié)點(diǎn)y的數(shù)據(jù)覆蓋z節(jié)點(diǎn) procedure tree_delete(z:longint); var x,y:longint; begin if (left[z]=0) or (right[z]=0) then y:=z else y:=tree_successor(z); if left[y]<>0 then x:=left[y] else x:=right[y]; if x<>0 then p[x]:=p[y]; if p[y]=0 then root:=x else begin if y=left[p[y]] then left[p[y]]:=x else right[p[y]]:=x; end; if z<>y then key[z]:=key[y]; end; 7.查找數(shù)中第k大元素 需要對(duì)每個(gè)節(jié)點(diǎn)新開一個(gè)域v[x],記錄該節(jié)點(diǎn)的有多少子節(jié)點(diǎn), 查找時(shí)分三種情況: (1)k=v[left[x]] 1 則當(dāng)前x節(jié)點(diǎn)為所求 (2)k<=v[left[x]] 則在左子樹中繼續(xù)查找 (3)k>v[left[x]] 1 則在右子樹中繼續(xù)查找,k更新為k-left[x]-1; function find(x,k:longint):longint; begin if v[left[x]] 1=k then exit(key[k]) else if v[left[x]]>=k then exit(find(left[x],k)) else exit(find(right[x],k-v[left[x]]-1)); end;