

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、9.1靜態(tài)查找表9.2動(dòng)態(tài)查找表9.3哈希表,目錄,第 九 章 查找,查找的基本概念,查找表(Search Table): 是由同一類型的數(shù)據(jù)元素(或記錄)構(gòu)成的集合。由于“集合”中的數(shù)據(jù)元素之間存在著完全松散的關(guān)系,因此查找表是一種非常靈便的數(shù)據(jù)結(jié)構(gòu)。,查找表的操作:1、查詢某個(gè)“特定的”數(shù)據(jù)元素是否在查找表中。2、檢索某個(gè)“特定的”數(shù)據(jù)元素的各種屬性。3、在查找表中插入一個(gè)數(shù)據(jù)元素;4、從
2、查找表中刪去某個(gè)數(shù)據(jù)元素。 靜態(tài)查找表: 對(duì)查找表只作前兩種操作,這兩種操作統(tǒng)稱為“查找”的操作,則稱此類查找表為靜態(tài)查找表。 動(dòng)態(tài)查找表: 在查找過(guò)程中同時(shí)插入查找表中不存在的數(shù)據(jù)元素,或者從查找表中刪除已存在的某個(gè)元素(也即元素集合可以根據(jù)情況動(dòng)態(tài)改變),則稱此類表為動(dòng)態(tài)查找表。,在日常生活中,人們幾乎每天都要進(jìn)行“查找”工作。例如,在電話號(hào)碼簿中查閱“某單位”或“某人”的電話號(hào)碼;在字典中查閱“某個(gè)詞”的讀單和含義等
3、等。其中“電話號(hào)碼簿”和“字典”都可視作是一張查找表。查找: 根據(jù)給定的某個(gè)值,在查找表中確定一個(gè)其關(guān)鍵字等于給定的記錄或數(shù)據(jù)元素。若表中存在這樣的一個(gè)記錄,則稱查找是成功的,此時(shí)查找的結(jié)果為給出整個(gè)記錄的信息,或指示該記錄在查找表中的位置;若表中不存在關(guān)鍵字等于給定值的記錄,則稱查找不成功。 關(guān)鍵字(關(guān)鍵碼)、主關(guān)鍵字、次關(guān)鍵字。 舉例:P214頁(yè)書(shū),(查找學(xué)生的高考成績(jī)),如何進(jìn)行查找呢?
4、 其實(shí),在一個(gè)結(jié)構(gòu)中查找某個(gè)數(shù)據(jù)元素的過(guò)程依賴于這個(gè)數(shù)據(jù)元素在結(jié)構(gòu)中所處的地位。因此,對(duì)表進(jìn)行查找的方法取決于表中數(shù)據(jù)元素依何種關(guān)系(這個(gè)關(guān)系是人為地加上的)組織在一起的。舉例:查電話號(hào)碼時(shí),由于電話號(hào)碼簿是按用戶(集體或個(gè)人)的名稱(或姓名)分類且依筆劃順序編排,則查找的方法就是先順序查找待查用戶的所屬類別,然后在此類中順序查找,直到找到該用戶的電話號(hào)碼為止。 又如,查閱英文單詞時(shí),由于字典是按單詞的字母在字
5、母表中的次序編排的,因此查找時(shí)不需要從字典中第一個(gè)單詞比較起,而只要根據(jù)待查單詞中每個(gè)字母在字母表中的位置查到該單詞。,同樣,在計(jì)算機(jī)中進(jìn)行查找的方法也隨數(shù)據(jù)結(jié)構(gòu)不同而不同。 但前面我們又說(shuō)到查找表中的數(shù)據(jù)元素之間存在著完全松散的關(guān)系,這給我們查找?guī)?lái)不便 。為此,需在數(shù)據(jù)元素之間人為地加上一些關(guān)系,以例按某種規(guī)則進(jìn)行查找,即以另一種數(shù)據(jù)結(jié)構(gòu)來(lái)表示查找表。,一些約定:典型的關(guān)鍵字類型說(shuō)明: typedef float
6、KeyType;//實(shí)型 typedef int KeyType;//整型typedef char *KeyType;//字符串型,數(shù)據(jù)元素類型定義為: typedef struct{ KeyType key; // 關(guān)鍵字域 . ..}ElemType;,,對(duì)兩個(gè)關(guān)鍵字的比較約定為如下的宏定義: 對(duì)數(shù)值型關(guān)鍵字#define EQ(a,b) ((a)==(b))#define LT(a,b)
7、((a)<(b))#define LQ(a,b) ((a)<=(b))對(duì)字符串型關(guān)鍵字#define EQ(a,b) (!strcmp((a),(b)))#define LT(a,b) (strcmp((a),(b))<0)#define LQ(a,b) (strcmp((a),(b))<=0),靜態(tài)查找表,靜態(tài)查找表的抽象數(shù)據(jù)類型定義:ADT StaticSearchTable{數(shù)據(jù)對(duì)象D:D
8、是具有相同特性的數(shù)據(jù)元素的集合。各個(gè)數(shù)據(jù)元素均含有類型相同,可唯一標(biāo)識(shí)數(shù)據(jù)元素的關(guān)鍵字。數(shù)據(jù)關(guān)系R:數(shù)據(jù)元素同屬一個(gè)集合?;静僮鱌:Create(&ST,n);操作結(jié)果:構(gòu)造一個(gè)含n個(gè)數(shù)據(jù)元素的靜態(tài)查找表ST。Destroy(&ST);初始條件:靜態(tài)查找表ST存在。操作結(jié)果:銷毀表ST。,9.1靜態(tài)查找法,Search(ST,key);初始條件:靜態(tài)查找表ST存在,key為和關(guān)鍵字類型相同的給定值
9、。操作結(jié)果:若ST中在在其關(guān)鍵字等于key的數(shù)據(jù)元素,則函數(shù)值為該元素的值或在表中的位置,否則為“空”。Traverse(ST,Visit());初始條件:靜態(tài)查找表ST存在,Visit是對(duì)元素操作的應(yīng)用函數(shù)。操作結(jié)果:按某種次序?qū)T的每個(gè)元素調(diào)用函數(shù)visit()一次且僅一次。一旦visit()失敗,則操作失敗。}ADT StaticSearchTable,順序表的查找,以順序表或線性鏈表表示靜態(tài)查找表,則Search
10、函數(shù)可用順序查找來(lái)實(shí)現(xiàn)。靜態(tài)查找表的順序存儲(chǔ)結(jié)構(gòu)typedef struct { ElemType *elem; //ElemType elem[100]; int length;}SSTable;順序查找:從表中最后一個(gè)記錄開(kāi)始,逐個(gè)進(jìn)行記錄的關(guān)鍵字和給定值的比較,若某個(gè)記錄的關(guān)鍵字和給定值比較相等,則查找成功,找到所查記錄;反之,查找不成功。int Search_Seq(SSTable S
11、T,KeyType key){ ST.elme[0].key=key; for(i=ST.length; !EQ(ST.elem[i].key,key); --i); return i;} 演示?。?查找操作的性能分析: 查找算法中的基本操作是將記錄的關(guān)鍵字和給定值進(jìn)行比較,通常以“其關(guān)鍵字和給定值進(jìn)行過(guò)比較的記錄
12、個(gè)數(shù)的平均值”作為衡量依據(jù)。平均查找長(zhǎng)度: 為確定記錄在查找表中的位置,需用和給定值進(jìn)行比較的關(guān)鍵字個(gè)數(shù)的期望值稱為查找算法在查找成功時(shí)的平均查找長(zhǎng)度(Average Search Length)。,其中:Pi為查找表中第i個(gè)記錄的概率,且 ;Ci為找到表中其關(guān)鍵字與給定值相等的第i個(gè)記錄時(shí),和給定值已進(jìn)行過(guò)比較的關(guān)鍵字個(gè)數(shù)。,對(duì)于含有n個(gè)記錄的表,查找成功時(shí)的平均查找長(zhǎng)度為:,假設(shè)
13、每個(gè)記錄的查找概率相等,即 Pi=1/n則在等概率情況下順序查找的平均查找長(zhǎng)度為:,假設(shè)查找成功與不成功的概率相同:,從順序查找的過(guò)程可見(jiàn),Ci取決于所查記錄在表中的位置。如:查找表中最后一個(gè)記錄時(shí),僅需比較一次;而查找表中第一個(gè)記錄時(shí),則需比較n次。一般情況下Ci=n-i+1; 假設(shè)n=ST.length,則順序查找的平均查找長(zhǎng)度為: ASL=n
14、P1+(n-1)P2+…..+2Pn-1+Pn,,前面總假設(shè)各個(gè)記錄的查找概率并不相等。但實(shí)際常常情況不是這樣,如果能預(yù)先知道每個(gè)記錄的查找概率,則應(yīng)先對(duì)記錄的查找概率進(jìn)行排序,使表中記錄按查找概率由小至大重新排列,以便提高查找效率。 但是,在一般情況下,記錄的查找概率預(yù)先無(wú)法測(cè)定。為了提高查找效率,我們可以在每個(gè)記錄中附設(shè)一個(gè)訪問(wèn)頻度域,并使順序表中的記錄始終不斷往后移,以例在以后的逐次查找中減少比較次數(shù)?;蛘咴诿看?/p>
15、查找之后都將剛查找到的記錄直接移至表尾。,有序表的查找(可以采用折半查找來(lái)實(shí)現(xiàn)),以有序表表示靜態(tài)查找表時(shí),Search函數(shù)可用折半查找來(lái)實(shí)現(xiàn)。 折半查找(Binary Search)的查找過(guò)程是:先確定待查記錄所在的范圍(區(qū)間),然后逐步縮小范圍直到找到或找不到該記錄為止。,見(jiàn)演示??!,折半查找的查找實(shí)現(xiàn)int Search_Bin(SSTable ST,KeyType key){ low=1;high=ST.le
16、ngth; while(low<=high) { mid=(low+high)/2; if EQ(key,ST.elem[mid].key) return mid; else if LT(key,ST.elem[mid].key)
17、 high=mid -1; else low=mid +1 ; } return 0;}//Search_Bin;,折半查找的性能分析 看書(shū)中的一個(gè)具體的情況,假設(shè):n=11i 12 3 4 5 6 7 8 9 10 11Ci 3 4 2 3 4
18、 1 3 4 2 3 4 現(xiàn)構(gòu)造一棵二叉樹(shù),將Ci=i的結(jié)點(diǎn)放在這棵樹(shù)的第i層該二叉樹(shù)可用以描述折半查找的過(guò)程,稱之謂“折半查找的判定樹(shù)”,折半查找在查找成功時(shí)和給定值進(jìn)行比較的關(guān)鍵字個(gè)數(shù)至多為:,例如: 折半查找在n=11 時(shí)的判定樹(shù)如下,一般情況下,表長(zhǎng)為n的折半查找的判定樹(shù)的深度和含有n個(gè)結(jié)點(diǎn)的完全二叉樹(shù)的深度相同,那末,折半查找的平均查找長(zhǎng)度是多少呢
19、? 假設(shè) n=2h-1 (反之,h=log2(n+1))并且查找概率相等則:,在n>50時(shí),可得近似結(jié)果,可見(jiàn),折半查找的效率比順序查找高,但折半查找只能適用于有序表,且限于順序存儲(chǔ)結(jié)構(gòu)(對(duì)線性鏈表無(wú)法進(jìn)行折半查找)。,索引順序表的查找 若以索引順序表表示靜態(tài)查找表,則Search函數(shù)可用分塊查找來(lái)實(shí)現(xiàn)。 分塊查找又稱索引順序查找,這是順序查找的一種改進(jìn)方法。在此查找法中
20、,除表本身以外,尚需建立一個(gè)“索引表”。,22 12 13 8 9 20 33 42 44 38 24 48 60 58 74 49 86 53,,,,,,,,,,,,,,,,,,48 861 7 13,,,,索引表,最大關(guān)鍵字 起始地址,,,,整個(gè)表中含有18個(gè)記錄,可分為三個(gè)子表(R1,R2,…,R6)、(R7,…,R1
21、2)、(R13,…,R18)對(duì)每個(gè)子表(或稱塊)建立一個(gè)索引項(xiàng),其中包括兩項(xiàng)內(nèi)容:最大關(guān)鍵字項(xiàng) 該子表的起始地址,對(duì)索引表按關(guān)鍵字有序,則表或者有序或者分塊有序。P225頁(yè)書(shū)劃上概念!,由于由索引項(xiàng)組成的索引表按關(guān)鍵字
22、有序,則確定塊的查找可以用順序查找,亦可用折半查找,而塊中記錄是任意排列的,則在塊中只能是順序查找。 由此,分塊查找的算法即為這兩種查找算法的簡(jiǎn)單合成。分塊查找的平均查找長(zhǎng)度為: ASLbs=Lb+ Lw其中: Lb為查找索引表確定所在塊的平均查找長(zhǎng)度, Lb為在塊中查找元素的平均查找長(zhǎng)度。 一般情況下,為進(jìn)行分塊查找,可以將長(zhǎng)度為n的表均勻地分成b塊,每塊
23、含有s個(gè)記錄,即b=[n/s];又假定表中每個(gè)記錄的查找概率相等,則每塊查找的概率為1/b,塊中每個(gè)記錄的查找概率為1/s。若用順序查找確定所在塊,則分塊查找的平均查找長(zhǎng)度為:,1.索引順序表: 存儲(chǔ)數(shù)據(jù)的表+索引;2.存儲(chǔ)方法: 數(shù)據(jù)分塊存放,且塊內(nèi)無(wú)序,但塊間有序; 每塊一個(gè)索引項(xiàng),包括塊地址和塊中最大數(shù)據(jù)值。3.查找方法: 首先在索引表中查找,索引是有序順序表,可以采
24、用折半查找方法;然后在 塊內(nèi)查找進(jìn)行(只能)是順序查找。,總結(jié):,9.2動(dòng)態(tài)查找法,動(dòng)態(tài)查找表的定義 動(dòng)態(tài)查找表的特點(diǎn)是: 表結(jié)構(gòu)本身是在查找過(guò)程中動(dòng)態(tài)生成的,即對(duì)于給定值key,若表中存在其關(guān)鍵字等于key的記錄,則查找成功返回,否則插入關(guān)鍵字等于key的記錄。以下是動(dòng)態(tài)查找表抽象數(shù)據(jù)類型的定義:,ADT DymanicSearchTable{ 數(shù)據(jù)對(duì)象D:D是具有相同特性的數(shù)據(jù)元素
25、的集合。各個(gè)數(shù)據(jù)元素均含有類型相同,可唯一標(biāo)識(shí)數(shù)據(jù)元素的關(guān)鍵字。 數(shù)據(jù)關(guān)系R:數(shù)據(jù)元素同屬一個(gè)集合。,特點(diǎn):用于頻繁進(jìn)行插入、刪除、查找的所謂動(dòng)態(tài)查找表。,基本操作P:InitDSTable(&DT);操作結(jié)果:構(gòu)造一個(gè)空的動(dòng)態(tài)查找表DT。DestroyDSTable(&DT);初始條件:動(dòng)態(tài)查找表DT存在;操作結(jié)果:銷毀動(dòng)態(tài)查找表DT。SearchDSTable(DT, key);初始條件:動(dòng)態(tài)查找
26、表DT存在,key為和關(guān)鍵字類型相同的給定值;操作結(jié)果:若DT中存在其關(guān)鍵字等于key的數(shù)據(jù)元素,則函數(shù)值為該元素的值或在表中的位置,否則為“空”。InsertDSTable(&DT, e);初始條件:動(dòng)態(tài)查找表DT存在,e為待插入的數(shù)據(jù)元素;操作結(jié)果:若DT中不存在其關(guān)鍵字等于e.key的數(shù)據(jù)元素,則插入e到DT。,DeleteDSTable(&T, key);初始條件:動(dòng)態(tài)查找表DT存在,key為和關(guān)鍵字類
27、型相同的給定值;操作結(jié)果:若DT中存在其關(guān)鍵字等于key的數(shù)據(jù)元素,則刪除之。TraverseDSTable(DT, Visit());初始條件:動(dòng)態(tài)查找表DT存在,Visit是對(duì)結(jié)點(diǎn)操作的應(yīng)用函數(shù);操作結(jié)果:按某種次序?qū)T的每個(gè)結(jié)點(diǎn)調(diào)用函數(shù)visit()一次且至多一次。一旦visit()失敗,則操作失敗。} ADT DynamicSearchTable,二叉排序樹(shù)及其查找過(guò)程 什么是二叉排序樹(shù)? 二叉排序樹(shù)
28、(Binary Sort Tree)或者是一棵空樹(shù); 或者是具有下列性質(zhì)的二叉樹(shù):1、若它的左子樹(shù)不空,則左子樹(shù)上所有結(jié)點(diǎn)的值均小于它的根結(jié)點(diǎn)的值;2、若它的右子樹(shù)不空,則右子樹(shù)上所有結(jié)點(diǎn)的值均大于它的根結(jié)點(diǎn)的值;3、它的左、右子樹(shù)了分別為二叉排序樹(shù)。,122,250,300,110,200,99,,,,,,L,N,P,
29、E,M,C,,,,,,Y,,105,,230,,216,,通常,取二叉鏈表作為二叉排序樹(shù)的存儲(chǔ)結(jié)構(gòu),二叉排序樹(shù)又稱二叉查找樹(shù),也可以稱為二叉分類樹(shù),1、分割式查找法: 查找步驟:若根結(jié)點(diǎn)的關(guān)鍵字值等于查找的關(guān)鍵字,成功。否則,若小于根結(jié)點(diǎn)的關(guān)鍵字值,查其左子樹(shù)。大于根結(jié)點(diǎn)的關(guān)鍵字值,查其右子樹(shù)。在左右子樹(shù)上的操作類似。,122,250,300,110,200,99,,,,,,105,,230,,216,,,BiTree
30、 SearchBST ( BiTree T, KeyType key ) // 在二叉分類樹(shù)查找關(guān)鍵字之值為 key 的結(jié)點(diǎn),找到返回該結(jié) // 點(diǎn)的地址,否則返回空。T 為二叉分類樹(shù)的根結(jié)點(diǎn)的地址。 { if ( ( !T) || EQ( key, T ->data. key ) ) return ( T ) ; else if ( LT( key , T ->dat
31、a. key ) ) return (SearchBST ( T -> lchild, key )); else return (SearchBST ( T -> rchild, key )); } // SearchBST,表示:typedef struct BiTNode { ElemType d
32、ata; struct BiTNode * lchild, *rchild; } BiTNode; *BiTree;,見(jiàn)演示!,2、插入算法: 首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。 判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左、右兒子。將被 插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。 若二叉樹(shù)為空。則首先單獨(dú)生成根結(jié)點(diǎn)。注意:新插入的結(jié)點(diǎn)總是葉子結(jié)點(diǎn)。,e、g:將數(shù)的序列:122、99
33、、250、110、300、280 作為二叉排序樹(shù)的結(jié) 點(diǎn)的關(guān)鍵字值,生成二叉排序樹(shù)。,2、插入算法: 首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。 判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左、右兒子。將被 插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。 若二叉樹(shù)為空。則首先單獨(dú)生成根結(jié)點(diǎn)。注意:新插入的結(jié)點(diǎn)總是葉子結(jié)點(diǎn)。,e、g:將數(shù)的序列:122、99、250、110、300、280 作為二叉排序樹(shù)的結(jié) 點(diǎn)的關(guān)鍵字值,生成二叉排序樹(shù)。,
34、122,2、插入算法: 首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。 判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左、右兒子。將被 插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。 若二叉樹(shù)為空。則首先單獨(dú)生成根結(jié)點(diǎn)。注意:新插入的結(jié)點(diǎn)總是葉子結(jié)點(diǎn)。,e、g:將數(shù)的序列:122、99、250、110、300、280 作為二叉排序樹(shù)的結(jié) 點(diǎn)的關(guān)鍵字值,生成二叉排序樹(shù)樹(shù)。,122,122,99,,2、插入算法: 首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。
35、判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左、右兒子。將被 插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。 若二叉樹(shù)為空。則首先單獨(dú)生成根結(jié)點(diǎn)。注意:新插入的結(jié)點(diǎn)總是葉子結(jié)點(diǎn)。,e、g:將數(shù)的序列:122、99、250、110、300、280 作為二叉排序樹(shù)的結(jié) 點(diǎn)的關(guān)鍵字值,生成二叉排序樹(shù)。,122,122,99,,122,250,99,,,2、插入算法: 首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。 判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左、右兒子。將被
36、插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。 若二叉樹(shù)為空。則首先單獨(dú)生成根結(jié)點(diǎn)。注意:新插入的結(jié)點(diǎn)總是葉子結(jié)點(diǎn)。,e、g:將數(shù)的序列:122、99、250、110、300、280 作為二叉排序樹(shù)的結(jié) 點(diǎn)的關(guān)鍵字值,生成二叉排序樹(shù)。,122,122,99,,122,250,99,,,122,250,110,99,,,,2、插入算法: 首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。 判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左、右兒子。將被 插結(jié)點(diǎn)作為葉
37、子結(jié)點(diǎn)插入。 若二叉樹(shù)為空。則首先單獨(dú)生成根結(jié)點(diǎn)。注意:新插入的結(jié)點(diǎn)總是葉子結(jié)點(diǎn)。,e、g:將數(shù)的序列:122、99、250、110、300、280 作為二叉排序樹(shù)的結(jié) 點(diǎn)的關(guān)鍵字值,生成二叉排序樹(shù)。,122,122,99,,122,250,99,,,122,250,110,99,,,,122,250,300,110,99,,,,,2、插入算法: 首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。 判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的
38、左、右兒子。將被 插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。 若二叉樹(shù)為空。則首先單獨(dú)生成根結(jié)點(diǎn)。注意:新插入的結(jié)點(diǎn)總是葉子結(jié)點(diǎn)。,122,250,300,110,280,99,,,,,,e、g:將數(shù)的序列:122、99、250、110、300、280 作為二叉排序樹(shù)的結(jié) 點(diǎn)的關(guān)鍵字值,生成二叉排序樹(shù)。,122,122,99,,122,250,99,,,122,250,110,99,,,,122,250,300,110,99,,,,,
39、2、插入算法:,Status SearchBST ( BiTree T,KeyType key, BiTree f,BiTree &p ) // 在二叉排序樹(shù) T 查找關(guān)鍵字之值為 key 的結(jié)點(diǎn)。初始時(shí) f 為 NULL。 // 如樹(shù)空,返回 p 為 NULL及 FALSE。如樹(shù)非空且查找成功,返回 p = T 及 TRUE。 // 如樹(shù)非空且查不成功,返回 p = f 及 FALS
40、E。f 為待插入結(jié)點(diǎn)的的父親結(jié)點(diǎn)的地址。 { if ( ( !T) { p = f; return FALSE; } else if ( EQ( key, T ->data. key ) ) { p = T; return TRUE; } else if ( LT( key , T ->data. key ) ) return (SearchBST ( T -> lchild, key
41、, T, p )); else return (SearchBST ( T -> rchild, key , T, p )); } // SearchBST,程序?qū)崿F(xiàn):,122,250,300,110,99,,,,,,,T,p,f:null,f: T 的父親結(jié)點(diǎn)p: 指向最后一個(gè)結(jié)點(diǎn),TRUE 找到;FALSE 葉子的父親結(jié)點(diǎn)。如:插入 280 的過(guò)程。,280,,2、插入算法:,執(zhí)行實(shí)
42、例:插入值為 280 的結(jié)點(diǎn),2、插入算法:,Status Inset BST ( BiTree &T, ElemType e ) // 在二叉排序樹(shù)中不存在 e.key 時(shí),插入并返回 TRUE,否則返回 FALSE。 { if ( ! SearchBST ( T,e.key,NULL,p ) { s = ( Bitree ) malloc ( sizeof ( BitNode ) ); s-&
43、gt;data = e; s->lchild = s->rchild = NULL; if ( ! p ) T = s; else if ( LT( e.key , p ->data. key ) ) p -> lchild = s; else p -> rchild = s; return TRUE; } return
44、FALSE; } // Insert BST,程序?qū)崿F(xiàn):,122,250,300,110,99,,,,,,,T,p,f: T 的父親結(jié)點(diǎn)p: 指向最后一個(gè)結(jié)點(diǎn),TRUE 找到;FALSE 葉子的父親結(jié)點(diǎn)。如:插入 280 的過(guò)程。,280,,f:null,,,15,60,70,30,20,,,,,50,,3、二叉排序樹(shù)的查找分析,平均情況分析(在成功查找兩種的情況下),e.g: 下述兩種情況下的成功的平均查找長(zhǎng)度 ASL
45、,15,60,70,30,20,,,,,50,,ASL=(1+2+2+3+3+3)/6=14/6,ASL=(1+2+3+4+5+6)/6=21/6,,,3、二叉排序樹(shù)的查找分析,平均情況分析(在成功查找兩種的情況下),在一般情況下,設(shè) P(n,i)且它的左子樹(shù)的結(jié)點(diǎn)個(gè)數(shù)為 i 時(shí)的平均查找長(zhǎng)度。右圖的結(jié)點(diǎn)個(gè)數(shù)為 n = 6 且 i = 3; 則 P(n,i)= P(6, 3) = [ 1+ ( P(3) + 1) * 3 + (
46、 P(2) + 1) * 2 ] / 6 = [ 1+ ( 5/3 + 1) * 3 + ( 3/2 + 1) * 2 ] / 6注意:這里 P(3)、P(2) 是具有 3 個(gè)結(jié)點(diǎn)、2 個(gè)結(jié)點(diǎn)的二叉排序樹(shù)的平均查找 長(zhǎng)度。 在一般情況下,P(i)為具有 i 個(gè)結(jié)點(diǎn)二叉排序樹(shù)的平均查找 長(zhǎng)度。 P(3
47、) = (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∴ n-1 P(n)= ∑ P(n,i)/ n i=0 = 1.465log2
48、n,15,60,70,30,20,,,,,50,,,,,左子樹(shù)0到n-1個(gè)結(jié)點(diǎn),右子樹(shù)n-1到0個(gè)結(jié)點(diǎn),,,4、二叉排序樹(shù)的刪除操作,葉子結(jié)點(diǎn):直接刪除,更改它的父親結(jié)點(diǎn)的相應(yīng)指針為空。如:刪除數(shù)據(jù)場(chǎng)為 15、70 的結(jié)點(diǎn)。,15,60,70,30,20,,,,,50,,60,30,20,,,,50,,,,子樹(shù)的根結(jié)點(diǎn):通常的做法:選取“ 替身”取代被刪結(jié)點(diǎn)。有資格充當(dāng)該替身的是誰(shuí)哪? 左子樹(shù)中最大的結(jié)點(diǎn) 或 右子樹(shù)中
49、最小的結(jié)點(diǎn),參看下圖。 要點(diǎn):維持二叉排序樹(shù)的特性不變。在中序遍歷 中緊靠著被刪結(jié)點(diǎn)的結(jié)點(diǎn) 才有資格作為“替身”。,,4、二叉排序樹(shù)的刪除操作,,,,,122,250,300,110,200,99,,,,,105,,230,,216,,,400,450,500,,,子樹(shù)的根結(jié)點(diǎn):
50、若被刪結(jié)點(diǎn)的左兒子為空或者右兒子為空。如下圖所示,刪除結(jié)點(diǎn)的數(shù)據(jù)場(chǎng)的關(guān)鍵字值為為 99 、300 的結(jié)點(diǎn)。,被刪結(jié)點(diǎn),,,122,250,300,200,,,,230,,216,,,400,450,500,,110,105,,,刪除,99,,4、二叉排序樹(shù)的刪除操作,,,,,122,250,300,110,200,99,,,,,105,,330,,316,,,400,450,500,,,被刪結(jié)點(diǎn),,,122,250,330,,,230
51、,216,,,400,450,500,,,刪除,300,110,99,,,105,,子樹(shù)的根結(jié)點(diǎn):若被刪結(jié)點(diǎn)的左兒子為空或者右兒子為空。如下圖所示,刪除結(jié)點(diǎn)的數(shù)據(jù)場(chǎng)的關(guān)鍵字值為為 99 、300 的結(jié)點(diǎn)。,316,,,,4、二叉排序樹(shù)的刪除操作,,,,,,122,250,300,110,200,99,,,,,105,,330,,316,,,400,450,500,,,,被刪結(jié)點(diǎn),結(jié)論:·將被刪結(jié)點(diǎn)的另一兒子作為它的父
52、 親結(jié)點(diǎn)的兒子,究竟是作為左兒子 還是右兒子依原替身結(jié)點(diǎn)和其父親 結(jié)點(diǎn)的關(guān)系而定。 ·釋放被刪結(jié)點(diǎn)的空間。,被刪結(jié)點(diǎn),子樹(shù)的根結(jié)點(diǎn):若被刪結(jié)點(diǎn)的左兒子為空或者右兒子為空。如下圖所示,刪除結(jié)點(diǎn)的數(shù)據(jù)場(chǎng)的關(guān)鍵字值為為 99 、300 的結(jié)點(diǎn)。,,,,4、二叉排序樹(shù)的刪除操作,子樹(shù)的根結(jié)點(diǎn):若被刪結(jié)點(diǎn)的左、右子樹(shù)皆不空,則: 通常的做
53、法:選取“替身”取代被刪結(jié)點(diǎn)。有資格充當(dāng)該替身的是誰(shuí)哪? 左子樹(shù)中最大的結(jié)點(diǎn)(被刪結(jié)點(diǎn)的左子樹(shù)中的最右的結(jié)點(diǎn),其右兒子指針場(chǎng)為空) 或 右子樹(shù)中最小的 結(jié)點(diǎn)(被刪結(jié)點(diǎn)的右子樹(shù)中的最左的結(jié)點(diǎn),其左兒子指針場(chǎng)為空) ,參看下圖。 要點(diǎn):維持二叉分類樹(shù)的特性不變。在中序周游中緊靠著被刪 結(jié)點(diǎn)的結(jié)點(diǎn)才有資格作為“替身”。,,,,,,122,250,300,110,200
54、,99,,,,,105,,330,316,,,400,450,500,,,,,被刪結(jié)點(diǎn),替身,替身,,,,110,250,300,105,200,99,,,,,330,,316,,,400,450,500,,做法:將替身的數(shù)據(jù)場(chǎng)復(fù)制到被刪結(jié) 點(diǎn)的數(shù)據(jù)場(chǎng)。 將結(jié)點(diǎn) 的左兒子作為 的父結(jié)點(diǎn)
55、 的右兒子。,110,110,99,注意:結(jié)點(diǎn) 右兒子必為空 結(jié)點(diǎn) 的父結(jié)點(diǎn)為,110,110,99,,,4、二叉排序樹(shù)的刪除操作,,,,,,,122,250,300,110,200,99,,,,,105,,330,,316,,,400,450,500,,,,,被刪結(jié)點(diǎn),替身,替身,,,,200,250,300,110,99,,,,105,,216,,40
56、0,450,500,,子樹(shù)的根結(jié)點(diǎn):若被刪結(jié)點(diǎn)的左、右子樹(shù)皆不空,則: 通常的做法:選取“替身”取代被刪結(jié)點(diǎn)。有資格充當(dāng)該替身的是誰(shuí)哪? 左子樹(shù)中最大的結(jié)點(diǎn)(被刪結(jié)點(diǎn)的左子樹(shù)中的最右的結(jié)點(diǎn),其右兒子指針場(chǎng)為空) 或 右子樹(shù)中最小的 結(jié)點(diǎn)(被刪結(jié)點(diǎn)的右子樹(shù)中的最左的結(jié)點(diǎn),其左兒子指針場(chǎng)為空) ,參看下圖。 要點(diǎn):維持二叉分類樹(shù)的特性不變。在中序周游中緊靠著
57、被刪 結(jié)點(diǎn)的結(jié)點(diǎn)才有資格作為“替身”。,做法:將替身的數(shù)據(jù)場(chǎng)復(fù)制到被刪結(jié) 點(diǎn)的數(shù)據(jù)場(chǎng)。 將結(jié)點(diǎn) 的右兒子作為 的父結(jié)點(diǎn) 的左兒子。,注意:結(jié)點(diǎn) 左兒子必為空 結(jié)點(diǎn) 的父結(jié)點(diǎn)為,200,200,200,2
58、00,250,330,,316,,,,4、二叉排序樹(shù)的刪除操作,,,,,,,122,250,300,110,200,99,,,,,105,,230,,216,,,400,450,500,,,,,被刪結(jié)點(diǎn),替身,替身,子樹(shù)的根結(jié)點(diǎn):若被刪結(jié)點(diǎn)的左、右子樹(shù)皆不空,則: 通常的做法:選取“替身”取代被刪結(jié)點(diǎn)。有資格充當(dāng)該替身的是誰(shuí)哪? 左子樹(shù)中最大的結(jié)點(diǎn)(被刪結(jié)點(diǎn)的左子樹(shù)中的最右的結(jié)點(diǎn),其右兒子指針場(chǎng)為空) 或 右子樹(shù)中最
59、小的 結(jié)點(diǎn)(被刪結(jié)點(diǎn)的右子樹(shù)中的最左的結(jié)點(diǎn),其左兒子指針場(chǎng)為空) ,參看下圖。 要點(diǎn):維持二叉分類樹(shù)的特性不變。在中序周游中緊靠著被刪 結(jié)點(diǎn)的結(jié)點(diǎn)才有資格作為“替身”。,結(jié)論:·先將替身的數(shù)據(jù)場(chǎng)復(fù)制到被刪結(jié)點(diǎn) ·將原替身的另一兒子作為它的父親 結(jié)點(diǎn)的兒子,究竟是作為左兒子還 是
60、右兒子依原替身結(jié)點(diǎn)和其父親結(jié) 點(diǎn)的關(guān)系而定。 ·釋放原替身結(jié)點(diǎn)的空間。,,4、二叉排序樹(shù)的刪除操作,,,,,F,S,,,C,,,,Q,,QL,,SL,,,,F,,C,,,,Q,,QL,,S,,SL,,F,,PL、PR皆 空, 直接刪除 。,PL或PR為空,,PL為空,刪除后的情況。,1.刪除法,2.刪除法,Status DeleteBST ( BiTree &T,Ke
61、yType key ) // 若二叉排序樹(shù) T 中存在關(guān)鍵字為 key 的結(jié)點(diǎn)時(shí),則刪除該結(jié)點(diǎn),并返回 TRUE; // 否則返回 FALSE。 { if ( ( !T) return FALSE; // 二叉排序樹(shù) T 中不存在關(guān)鍵字為 key 的結(jié)點(diǎn) else if ( EQ( key, T ->data. key ) ) Delete (T); // 存在關(guān)鍵字為 key 的
62、結(jié)點(diǎn),進(jìn)行刪除 else if ( LT( key , T ->data. key ) ) DeleteBST ( T -> lchild, key ); else DeleteBST ( T -> rchild, key ); return TRUE; } // DeleteBST,程序?qū)崿F(xiàn):,4、二叉排序樹(shù)的刪除操作,Status Delete
63、( BiTree &p ) // 在二叉排序樹(shù)中刪除地址為 p 的結(jié)點(diǎn),并保持二叉排序樹(shù)的性質(zhì)不變。 { if ( ! p-> rchild ) { q = p; p = p->lchild ; free(q); } // 參考下頁(yè) else if ( ! p-> lchild ) { q = p; p = p->rchild ; free(q); }
64、else { q = p; s = p-> lchild; while ( s->rchild ) { q = s; s = s->rchild; } p->data = s->data; if ( q != p ) q->rchild = s->lchild;
65、 else q->lchild = s->lchild; free(s); } } // DeleteBST,程序?qū)崿F(xiàn):,4、二叉排序樹(shù)的刪除操作,注意:刪除根結(jié)點(diǎn)而相應(yīng)的二叉樹(shù)沒(méi)有另增的頭結(jié)點(diǎn)的情況。,,,被刪結(jié)點(diǎn) P,,,若:P -> rchild == NULL,,,被刪結(jié)點(diǎn) f,,原 f->lchild 即為 P ;現(xiàn) p=p-&g
66、t;lchild故 f->lchild 即為 PL,二叉排序樹(shù)的插入,二叉排序樹(shù)是一種動(dòng)態(tài)樹(shù)表,其特點(diǎn)是,樹(shù)的結(jié)構(gòu)通常不是一次生成的,而是在查找過(guò)程中,當(dāng)樹(shù)中不存在關(guān)鍵字等于給定值的結(jié)點(diǎn)時(shí)再進(jìn)行插入。新插入的結(jié)點(diǎn)一定是一個(gè)新添加的葉子結(jié)點(diǎn),并且是查找不成功時(shí)查找路徑上訪問(wèn)的最后一個(gè)結(jié)點(diǎn)的左孩子或右孩子結(jié)點(diǎn)。,Status SearchBST(BiTree T,KeyType key,BiTree f,BiTree &p)
67、{ if(!T) {p=f;return FALSE;} else if EQ(key,T->data.key) { p=T;return TRUE;} else if LT(key,T->data.key)
68、 SearchBsT(T->lchild,key,T,p); else SearchBST(T->rchild,key,T,p);}//SearchBST,見(jiàn)演示!!,插入算法:Status InsertBST(BiTree &T,ElemType e){ if(!SearchBST(T,e.key,NUL
69、L,p) { s=(BiTree)malloc(sizeof(BiTNode)); s->data=e;s->lchild=s->rchild=NULL; if(!p) T=s; else if (LT(e.key,p-
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《數(shù)據(jù)結(jié)構(gòu)》習(xí)題集第9章_查找
- 第3章_數(shù)據(jù)結(jié)構(gòu)
- 《數(shù)據(jù)結(jié)構(gòu)》講義
- 數(shù)據(jù)結(jié)構(gòu)講義
- 《數(shù)據(jù)結(jié)構(gòu)》講義
- 數(shù)據(jù)結(jié)構(gòu)第1章-答案
- 數(shù)據(jù)結(jié)構(gòu)答案第5章
- 數(shù)據(jù)結(jié)構(gòu)課后習(xí)題(第1章)
- 數(shù)據(jù)結(jié)構(gòu) 學(xué)習(xí)講義 08
- 數(shù)據(jù)結(jié)構(gòu) 第2章 線性表
- 數(shù)據(jù)結(jié)構(gòu)習(xí)題解析第10章
- 數(shù)據(jù)結(jié)構(gòu)習(xí)題解析第6章
- 廣工anyview數(shù)據(jù)結(jié)構(gòu)第15章答案
- 數(shù)據(jù)結(jié)構(gòu) 第5章數(shù)組和廣義表
- 數(shù)據(jù)結(jié)構(gòu)第05章 數(shù)組和廣義表
- 數(shù)據(jù)結(jié)構(gòu)第4章串b教學(xué)ppt
- 零基礎(chǔ)學(xué)數(shù)據(jù)結(jié)構(gòu) 第4章 棧-
- 數(shù)據(jù)結(jié)構(gòu)第11講
- 數(shù)據(jù)結(jié)構(gòu)第13周
- 數(shù)據(jù)結(jié)構(gòu)第在線作業(yè)
評(píng)論
0/150
提交評(píng)論