




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第七章搜索結構數據結構電子教案本章的主要內容是:搜索的基本概念線性表的搜索技術樹表的搜索技術散列表的搜索技術3所謂搜索,就是在數據集合中尋找滿足某種條件的數據對象。搜索的結果通常有兩種可能:搜索成功搜索不成功
搜索(Search)的概念基本概念關鍵碼:可以標識一個記錄的某個數據項。鍵值:關鍵碼的值。主關鍵碼:可以唯一地標識一個記錄的關鍵碼。
次關鍵碼:不能唯一地標識一個記錄的關鍵碼。7.1概述50女李爽000525女齊梅000447女劉楠000325男張亮000238男王剛0001年齡性別姓名職工號1972.92003.71979.92003.71990.4工作時間靜態(tài)搜索:不涉及插入和刪除操作的搜索。動態(tài)搜索:涉及插入和刪除操作的搜索。
7.1概述查找的基本概念靜態(tài)搜索適用于:搜索集合一經生成,便只對其進行搜索,而不進行插入和刪除操作,或經過一段時間的搜索之后,集中地進行插入和刪除等修改操作;動態(tài)搜索適用于:查找與插入和刪除操作在同一個階段進行,例如當查找成功時,要刪除查找到的記錄,當查找不成功時,要插入被查找的記錄。7.1概述基本概念搜索結構:面向搜索操作的數據結構,即搜索基于的數據結構。查找結構
查找方法
集合中元素之間不存在明顯的組織規(guī)律,不便查找。集合
線性表
樹表
散列表
本章討論的搜索結構:線性表:適用于靜態(tài)搜索,主要采用順序搜索技術和折半搜索技術。樹表:適用于動態(tài)搜索,主要采用二叉排序樹的搜索技術。散列表:靜態(tài)查找和動態(tài)查找均適用,主要采用散列技術。
7.1概述基本概念搜索算法的性能
搜索算法時間性能通過關鍵碼的比較次數來度量。7.1概述關鍵碼的比較次數與哪些因素有關呢?平均搜索長度:將搜索算法進行的關鍵碼的比較次數的數學期望值定義為平均搜索長度,即:其中:n:問題規(guī)模,查找集合中的記錄個數;
pi:搜索第i個記錄的概率;ci:搜索第i個記錄所需的關鍵碼的比較次數。ASL?==niiicp1搜索算法的性能
7.1概述ASL?==niiicp1ci取決于算法;pi與算法無關,取決于具體應用。如果pi是已知的,則平均查找長度只是問題規(guī)模的函數。在靜態(tài)搜索表中,數據元素存放于數組中,利用數組元素的下標作為數據元素的存放地址。搜索算法根據給定值k,在數組中進行搜索。直到找到k在數組中的存放位置或可確定在數組中找不到
k為止。
7.1.1靜態(tài)搜索表11數據表與搜索表的類定義
#include<iostream.h>#include<assert.h>constintdefaultSize=100;template<classE,classK>classdataList; //數據表類的前視定義template<classE,classK>classdataNode{ //數據表中結點類的定義friendclassdataList<E,K>; private:
Kkey; //關鍵碼域
E
other; //其他域(視問題而定)
//聲明其友元類為dataListpublic:12
dataNode(constKx):key(x){} //構造函數
KgetKey()const{returnkey;} //讀取關鍵碼
voidsetKey(Kx){key=x;} //修改關鍵碼};template<classE,classK>classdataList{ //數據表類定義protected:
dataNode<E,K>*Element; //數據表存儲數組
intArraySize,CurrentSize; //數組最大長度和當前長度13順序搜索主要用于在線性表中搜索。順序用各元素的關鍵碼與給定值x進行比較技巧:把待查關鍵字key存入表頭或表尾(俗稱“哨兵”),這樣可以加快執(zhí)行速度。7.1.2順序搜索(SequentialSearch)
順序查找(線性查找)基本思想:從線性表的一端向另一端逐個將關鍵碼與給定值進行比較,若相等,則查找成功,給出該記錄在表中的位置;若整個表檢測完仍未找到與給定值相等的關鍵碼,則查找失敗,給出失敗信息。
101524612354098550123456789i例:查找k=35iii順序查找(線性查找)intSeqSearch1(intr[],intn,intk)//數組r[1]~r[n]存放查找集合{i=n;while(i>0&&r[i]!=k)i--;returni;}基本思想:設置“哨兵”。哨兵就是待查值,將它放在查找方向的盡頭處,免去了在查找過程中每一次比較后都要判斷查找位置是否越界,從而提高查找速度。
改進的順序查找101524612354098550123456789i例:查找k=35iii哨兵35查找方向基本思想:設置“哨兵”。哨兵就是待查值,將它放在查找方向的盡頭處,免去了在查找過程中每一次比較后都要判斷查找位置是否越界,從而提高查找速度。
改進的順序查找101524612354098550123456789i例:查找k=25ii25查找方向iiiiiiiintSeqSearch2(intr[],intn,intk)//數組r[1]~r[n]存放查找集合{r[0]=k;i=n;while(r[i]!=k)i--;returni;}改進的順序查找
ASL==?=niicp1?+-=niiinp1)1(i=(n+1)/2=O(n)平均查找長度較大,特別是當待查找集合中元素較多時,查找效率較低。順序查找的缺點:對表中記錄的存儲沒有任何要求,順序存儲和鏈接存儲均可;對表中記錄的有序性也沒有要求,無論記錄是否按關鍵碼有序均可。順序查找的優(yōu)點:算法簡單而且使用面廣。7.1.3基于有序順序表的折半搜索哨兵法當N很大時,搜索的效率很低。如果把順序表的元素按其關鍵碼從小到大排列,則可以采取效率更高的搜索算法。20折半搜索使用條件:線性表中的記錄必須按關鍵碼有序;必須采用順序存儲。基本思想:折半搜索時,先求位于搜索區(qū)間正中的對象的下標mid,用其關鍵碼與給定值x比較:Element[mid].key==x,搜索成功;
Element[mid].key>x,把搜索區(qū)間縮小到表的前半部分,繼續(xù)折半搜索;
Element[mid].key<x,把搜索區(qū)間縮小到表的后半部分,繼續(xù)折半搜索。例:查找值為14的記錄的過程:
012345678910111213
7141821232931353842464952low=1high=13mid=7
high=6mid=3
high=2
mid=1
31>1418>147<14low=2mid=2
14=14例:查找值為22的記錄的過程:
012345678910111213
7141821232931353842464952low=1high=13mid=7
high=6mid=3
high=4
mid=5
31>2218<2223>22low=4mid=4
21<22low=5low>highintBinSearch1(intr[],intn,intk){//數組r[1]~r[n]存放查找集合low=1;high=n;while(low<=high){
mid=(low+high)/2;if(k<r[mid])high=mid-1;elseif(k>r[mid])low=mid+1;elsereturnmid;}return0;}折半查找——非遞歸算法intBinSearch2(intr[],intlow,inthigh,intk){//數組r[1]~r[n]存放查找集合if(low>high)return0;
else{mid=(low+high)/2;if(k<r[mid])returnBinSearch2(r,low,mid-1,k);elseif(k>r[mid])returnBinSearch2(r,mid+1,high,k);elsereturnmid;}}折半查找——遞歸算法有序順序表的折半搜索的判定樹
(10,20,30,40,50,60)1050======30<<<<<<>>>>>>204060(2*1+3*6)/7折半搜索性能分析若設n=2h-1,則描述折半搜索的判定樹是高度為h-1的滿二叉樹。
2h=n+1,h=log2|
(n+1)︱。搜索成功:在表中查找任一記錄的過程,即是折半查找判定樹中從根結點到該記錄結點的路徑,和給定值的比較次數等于該記錄結點在樹中的層數。搜索不成功:查找失敗的過程就是走了一條從根結點到外部結點的路徑,和給定值進行的關鍵碼的比較次數等于該路徑上內部結點的個數??梢杂脷w納法證明課堂練習(多項選擇):A.采用鏈式存貯結構 B.記錄的長度≤128C.采用順序存貯結構D.記錄按關鍵字遞增有序√√使用折半查找算法時,要求被查文件:307.2二叉搜索樹(BinarySearchTree)定義
二叉搜索樹或者是一棵空樹,或者是具有下列性質的二叉樹:所有結點的關鍵碼互不相同。左子樹(如果非空)上所有結點的關鍵碼都小于根結點的關鍵碼。右子樹(如果非空)上所有結點的關鍵碼都大于根結點的關鍵碼。左子樹和右子樹也是二叉搜索樹。351545504025102030二叉搜索樹例結點左子樹上所有關鍵碼小于結點關鍵碼;右子樹上所有關鍵碼大于結點關鍵碼;(a)(b)練:下列2種圖形中,哪個不是二叉搜索樹?如果對一棵二叉搜索樹進行中序遍歷,可以按從小到大的順序,將各結點關鍵碼排列起來,所以也稱二叉搜索樹為二叉排序樹。二叉搜索樹的類定義#include<iostream.h>#include<stdlib.h>template<classE,classK>structBSTNode{ //二叉樹結點類
Edata; //數據域
BSTNode<E,K>*left,*right;//左子女和右子女BSTNode(){left=NULL;right=NULL;
}
BSTNode(constEd,BSTNode<E,K>*L=NULL,
BSTNode<E,K>*R=NULL){data=d;left=L;right=R;}~BSTNode(){} //析構函數
voidsetData(Ed){data=d;} //修改
EgetData(){returndata;} //提取
booloperator<(constE&x)
//重載:判小于
{returndata.key<x.key;}
booloperator>(constE&x) //重載:判大于
{returndata.key>x.key;}booloperator==(constE&x) //重載:判等于
{returndata.key==x.key;}};template<classE,classK>classBST{ //二叉搜索樹類定義private:BSTNode<E,K>*root; //根指針
KRefValue; //輸入停止標志public:BST(){root=NULL;
} //構造函數
BST(Kvalue); //構造函數
~BST(){}; //析構函數
boolSearch(constKx)const //搜索
{returnSearch(x,root)!=NULL;}
BST<E,K>&operator=(constBST<E,K>&R); //重載:賦值
voidmakeEmpty()
//置空
{makeEmpty(root);root=NULL;}voidPrintTree()const{PrintTree(root);}//輸出
EMin(){returnMin(root)->data;} //求最小
EMax(){returnMax(root)->data;} //求最大
boolInsert(constE&e1)
//插入新元素
{returnInsert(e1,root);}boolRemove(constKx){returnRemove(x,root);} //刪除含x的結點private:
BSTNode<E,K>* //遞歸:搜索
Search(constKx,BSTNode<E,K>*ptr);voidmakeEmpty(BSTNode<E,K>*&ptr); //遞歸:置空
voidPrintTree(BSTNode<E,K>*ptr)const; //遞歸:打印
BSTNode<E,K>* //遞歸:復制
Copy(constBSTNode<E,K>*ptr); BSTNode<E,K>*Min(BSTNode<E,K>*ptr);
//遞歸:求最小
BSTNode<E,K>*Max(BSTNode<E,K>*ptr);
//遞歸:求最大
boolInsert(constE&e1,BSTNode<E,K>*&ptr);
//遞歸:插入
boolRemove(constKx,BSTNode<E,K>*&ptr);
//遞歸:刪除};二叉搜索樹的類定義用二叉鏈表作為它的存儲表示,許多操作的實現與二叉樹類似。二叉搜索樹的搜索算法在二叉搜索樹上進行搜索,是一個從根結點開始,遞歸進行比較判等的過程。假設想要在二叉搜索樹中搜索關鍵碼為x
的元素,搜索過程從根結點開始。如果根指針為NULL,則搜索不成功;否則用給定值
x
與根結點的關鍵碼進行比較:若給定值等于根結點關鍵碼,則搜索成功若小于根結點的關鍵碼,則搜索左子樹;否則。遞歸搜索根結點的右子樹。搜索45搜索成功搜索28搜索失敗351545504025102030template<classE,classK>BSTNode<E,K>*BST<E,K>::Search(constKx,BSTNode<E,K>*ptr){//私有遞歸函數:在以ptr為根的二叉搜索樹中搜//索含x的結點。若找到,則函數返回該結點的//地址,否則函數返回NULL值。
if(ptr==NULL)returnNULL;
elseif(x<ptr->data)returnSearch(x,ptr->left);elseif(x>ptr->data)returnSearch(x,ptr->right);elsereturnptr; //搜索成功};template<classE,classK>BSTNode<E,K>*BST<E,K>::Search(constKx,BSTNode<E,K>*ptr){//非遞歸函數:作為對比,在當前以ptr為根的二//叉搜索樹中搜索含x的結點。若找到,則函數返//回該結點的地址,否則函數返回NULL值。
if(ptr==NULL)returnNULL;
BSTNode<E,K>*temp=ptr;while(temp!=NULL){
if(x==temp->data)returntemp;
if(x<temp->data)
temp=temp->left;elsetemp=temp->right;}returnNULL;};搜索過程是從根結點開始,沿某條路徑自上而下逐層比較判等的過程。搜索成功,搜索指針將停留在樹上某個結點;搜索不成功,搜索指針將走到樹上某個結點的空子樹。設樹的高度為h,最多比較次數不超過h。二叉搜索樹的插入算法為了向二叉搜索樹中插入一個新元素,必須先檢查這個元素是否在樹中已經存在。在插入之前,先使用搜索算法在樹中檢查要插入元素有還是沒有。如果搜索成功,說明樹中已經有這個元素,不再插入;如果搜索不成功,說明樹中原來沒有關鍵碼等于給定值的結點,把新元素加到搜索操作停止的地方。35154550402510203028插入新結點28二叉搜索樹的插入每次結點的插入,都要從根結點出發(fā)搜索插入位置,然后把新結點作為葉結點插入。二叉搜索樹的插入算法template<classE,classK>boolBST<E,K>::Insert(constE&e1,BSTNode<E,K>*&ptr){
if(ptr==NULL){ //新結點作為葉結點插入
ptr=newBstNode<E,K>(e1); //創(chuàng)建新結點
if(ptr==NULL){cerr<<"Outofspace"<<endl;exit(1);} returntrue;}elseif(e1<ptr->data)Insert(e1,ptr->left);
elseif(e1>ptr->data)Insert(e1,ptr->right);
elsereturnfalse; //x已在樹中,不再插入};利用二叉搜索樹的插入算法,可以很方便地建立二叉搜索樹。
輸入數據
{53,78,65,17,87,09,81,15}535378537865537865175378658717537865091787537865811787095378651517870981template<classE,classK>BST<E,K>::BST(Kvalue){//輸入一個元素序列,建立一棵二叉搜索樹
Ex;
root=NULL;RefValue=value; //置空樹
cin>>x; //輸入數據
while(x.key!=RefValue){ //RefValue是一個輸入結束標志
Insert(x,root);cin>>x; //插入,再輸入數據
}};在二叉排序樹上刪除某個結點之后,仍然保持二叉排序樹的特性。分三種情況討論:被刪除的結點是葉子;被刪除的結點只有左子樹或者只有右子樹;被刪除的結點既有左子樹,也有右子樹。
二叉搜索樹的刪除情況1——被刪除的結點是葉子結點二叉搜索樹的刪除50302080908588403532503020809085403532操作:將雙親結點中相應指針域的值改為空。情況2——被刪除的結點只有左子樹或者只有右子樹操作:將雙親結點的相應指針域的值指向被刪除結點的左子樹(或右子樹)。q=pp=p->lchild(或p=p->rchild);free(q)二叉搜索樹的刪除50302080908588403532503020908588403532qp8853788117940945刪除78在右子樹上找中序下第一個結點填補2365538188179409452365情況3:被刪結點左、右子樹都不為空,以其左子樹中的最大值結點(或右子樹中的最小值結點)替代之,再來處理這個結點的刪除問題。情況3——被刪除的結點既有左子樹也有右子樹二叉搜索樹的刪除50302080908588403532403020809085883532二叉搜索樹的刪除算法template<classE,classK>boolBST<E,K>::Remove(constKx,
BstNode<E,K>*&ptr){//在以ptr為根的二叉搜索樹中刪除含x的結點
BstNode<E,K>*temp;if(ptr!=NULL){if(x<ptr->data)Remove(x,ptr->left);
//在左子樹中執(zhí)行刪除
elseif(x>ptr->data)Remove(x,ptr->right);
//在右子樹中執(zhí)行刪除elseif(ptr->left!=NULL&&ptr->right!=NULL)
{//ptr指示關鍵碼為x的結點,它有兩個子女
temp=ptr->right;
//到右子樹搜尋中序下第一個結點
while(temp->left!=NULL)temp=temp->left;
ptr->data=temp->data;
//用該結點數據代替根結點數據
Remove(ptr->data,ptr->right);} else{ //ptr指示關鍵碼為x的結點有一個子女
temp=ptr; if(ptr->left==NULL)ptr=ptr->right;elseptr=ptr->left;deletetemp;returntrue;} } returnfalse;};注意在刪除算法參數表引用型指針參數的使用。
二叉搜索樹性能分析對于有n個關鍵碼的集合,其關鍵碼有n!種不同排列,可構成不同二叉搜索樹有
(棵)
{2,1,3}{1,2,3}{1,3,2}{2,3,1}{3,1,2}{3,2,1}
123111132223323同樣3個數據{1,2,3},輸入順序不同,建立起來的二叉搜索樹的形態(tài)也不同。這直接影響到二叉搜索樹的搜索性能。如果輸入序列選得不好,會建立起一棵單支樹,使得二叉搜索樹的高度達到最大。用樹的搜索效率來評價這些二叉搜索樹。為此,在二叉搜索樹中加入外結點,形成判定樹。外結點表示失敗結點,內結點表示搜索樹中已有的數據。這樣的判定樹即為擴充的二叉搜索樹。舉例說明。已知關鍵碼集合
{a1,a2,a3}=
{do,if,to},對應搜索概率p1,p2,p3,在各搜索不成功間隔內搜索概率分別為q0,q1,q2,q3??赡艿亩嫠阉鳂淙缦滤?。doiftodoiftoq0q1p1q2p2q3p3q0q1q2q3p1p2p3(a)(b)判定樹doiftoq0q1p1q2p2q3p3doiftoq0q1p1q2p2q3p3(d)(c)doiftoq0q1p1q2p2q3p3(e)在判定樹中
○表示內部結點,包含了關鍵碼集合中的某一個關鍵碼;□表示外部結點,代表各關鍵碼間隔中的不在關鍵碼集合中的關鍵碼。一棵判定樹上的搜索成功的平均搜索長度ASLsucc可以定義為該樹所有內部結點上的搜索概率p[i]與搜索該結點時所需的關鍵碼比較次數c[i](=l[i],即結點所在層次)乘積之和:設各關鍵碼的搜索概率相等:p[i]=1/n搜索不成功的平均搜索長度ASLunsucc為樹中所有外部結點上搜索概率q[j]與到達外部結點所需關鍵碼比較次數c'[j](=l'[j])乘積之和:設外部結點搜索概率相等:q[j]=1/(n+1):設樹中所有內、外部結點的搜索概率都相等:
p[i]=1/3,1≤i≤3,q[j]=1/4,0≤
j≤3
圖(a):ASLsucc=1/3*3+1/3*2+1/3*1=6/3,
ASLunsucc=1/4*3*2+1/4*2+1/4*1=9/4。
圖(b):
ASLsucc=1/3*2*2+1/3*1=5/3,
ASLunsucc=1/4*2*4=8/4。圖(c):ASLsucc=1/3*1+1/3*2+1/3*3=6/3,
ASLunsucc=1/4*1+1/4*2+1/4*3*2=9/4。圖(d):ASLsucc=1/3*2+1/3*3+1/3*1=6/3,
ASLunsucc=1/4*2+1/4*3*2+1/4*1=9/4。(1)相等搜索概率的情形
圖(e):ASLsucc=1/3*1+1/3*3+1/3*2=6/3,
ASLunsucc=1/4*1+1/4*3*2+1/4*2=9/4。圖(b)的情形所得的平均搜索長度最小。一般把平均搜索長度達到最小的擴充的二叉搜索樹稱作最優(yōu)二叉搜索樹。在相等搜索概率的情形下,所有內部、外部結點的搜索概率都相等,視它們的權值都為1。同時,第k層有2k-1個結點,k=1,2,。則有n個內部結點的擴充二叉搜索樹的內部路徑長度I至少等于序列
0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,…
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 合同達成!中醫(yī)醫(yī)院醫(yī)療設備升級改造項目揭曉
- 吊車租賃合同書
- 員工保密合同協議書樣本
- 企業(yè)與員工解除勞動合同合同書
- 兼職人員薪資合同協議
- 2025年銅合金緩蝕助劑行業(yè)深度研究分析報告
- 度債轉股合同執(zhí)行協議
- 建筑裝修工程承包合同(示范文本)
- 預應力鋼筋工程專業(yè)施工合同6篇
- 實習協議書合同8篇
- 人音版(2019)高中 必修《音樂鑒賞》 5.9 獨唱曲 課件(19張PPT)
- 《比較教育學》教學大綱
- 文件袋、檔案袋密封條模板
- 新東方詞匯亂序版
- 租賃(出租)物品清單表
- 高處安全作業(yè)票填寫模板(2022更新)
- 小學生幼兒園文明禮儀教育主題班會(可愛卡通版)
- 新道路貨物運輸企業(yè)質量信譽考核檔案
- 國際收付清算體系與實務從原理看SWIFT
- 廣東海事局轄區(qū)主要防臺錨地或泊區(qū)情況表
- 風險與機遇識別評價表
評論
0/150
提交評論