




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
摘要查找是在大量的信息中尋找一個特定的信息元素,在計算機應用中,查找是常用的基本運算。文中介紹四種查找算法.分別是順序查找、二分查找、二叉排序樹查找和哈希查找。并用JAVA語言編寫了相應程序代碼,比較了查找同一個數據的時間復雜度和空間復雜度。關鍵詞:查找算法;時間復雜度;空間復雜度AbstractSearchingisacommonlybasicoperationthatcanfindanumberofinformationincomputerapplications.Inthispaper,fourtapyesofsearchingalgorithmareintroduced.Theyaresquentialearch,binarysearchtree,andbashsearch.Theprogarm’scodesbasedonjavaarecomplied.Thetimecomplexityandspacecomplexitytolookforthesamedataandcompared.Keywords:SearchingAlgorithm;Timecomplexity;Spacecomplexity目錄摘要 11算法概述 11.1引言 11.2順序查找 21.3二分查找 21.3.1二分查找要求 21.3.2優(yōu)缺點 21.3.3算法思想 21.3.4算法復雜度 31.4分塊查找 31.4.1方法描述 31.4.2操作步驟 31.5哈希表查找 41.5.1基本原理 41.5.2函數構造 41.5.3沖突處理 41.5.4支持運算 42算法實現 72.1順序查找 72.1.1方法分類 72.2二分查找 82.2.1算法要求 82.2.2算法復雜度 82.2.3代碼示例 92.2.4遞歸實現 112.3分塊查找 162.3.1方法描述 162.3.2操作步驟 172.4哈希表查找 182.4.1操作步驟 182.4.2解決沖突 193比較與總結 223.1分類查找的依據 223.2效率比較 22參考文獻 241算法概述1.1引言用關鍵字標識一個數據元素,查找時根據給定的某個值,在表中確定一個關鍵字的值等于給定值的記錄或數據元素。在計算機中進行查找的方法是根據表中的記錄的組織結構確定的。順序查找也稱為線形查找,從數據結構線形表的一端開始,順序掃描,依次將掃描到的結點關鍵字與給定值k相比較,若相等則表示查找成功;若掃描結束仍沒有找到關鍵字等于k的結點,表示查找失敗。二分查找要求線形表中的結點按關鍵字值升序或降序排列,用給定值k先與中間結點的關鍵字比較,中間結點把線形表分成兩個子表,若相等則查找成功;若不相等,再根據k與該中間結點關鍵字的比較結果確定下一步查找哪個子表,這樣遞歸進行,直到查找到或查找結束發(fā)現表中沒有這樣的結點。分塊查找也稱為索引查找,把線形分成若干塊,在每一塊中的數據元素的存儲順序是任意的,但要求塊與塊之間須按關鍵字值的大小有序排列,還要建立一個按關鍵字值遞增順序排列的索引表,索引表中的一項對應線形表中的一塊,索引項包括兩個內容:1)鍵域存放相應塊的最大關鍵字;2)鏈域存放指向本塊第一個結點的指針。分塊查找分兩步進行,先確定待查找的結點屬于哪一塊,然后在塊內查找結點。哈希表查找是通過對記錄的關鍵字值進行運算,直接求出結點的地址,是關鍵字到地址的直接轉換方法,不用反復比較。假設f包含n個結點,Ri為其中某個結點(1≤i≤n),keyi是其關鍵字值,在keyi與Ri的地址之間建立某種函數關系,可以通過這個函數把關鍵字值轉換成相應結點的地址,有:addr(Ri)=H(keyi),addr(Ri)為哈希函數。1.2順序查找順序查找過程:從表中的最后一個記錄開始,逐個進行記錄的關鍵字與給定值進行比較,若某個記錄的關鍵字與給定值相等,則查找成功,找到所查的記錄;反之,若直到第一個記錄,其關鍵字和給定值比較都不相等,則表明表中沒有所查的記錄,查找失敗。算法描述為:intSearch(intd,inta[],intn){/*在數組a[]中查找等于D元素,若找到,則函數返回d在數組中的位置,否則為0。其中n為數組長度*/inti;/*從后往前查找*/for(i=n-1;a!=d;--i)此處程序正確嗎?returni;/*如果找不到,則i為0*/}1.3二分查找二分查找又稱折半查找,它是一種效率較高的查找方法。1.3.1二分查找要求1)必須采用順序存儲結構。2)必須按關鍵字大小有序排列。1.3.2優(yōu)缺點折半查找法的優(yōu)點是比較次數少,查找速度快,平均性能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查找方法適用于不經常變動而查找頻繁的有序列表。1.3.3算法思想首先,將表中間位置記錄的關鍵字與查找關鍵字比較,如果兩者相等,則查找成功;否則利用中間位置記錄將表分成前、后兩個子表,如果中間位置記錄的關鍵字大于查找關鍵字,則進一步查找前一子表,否則進一步查找后一子表。重復以上過程,直到找到滿足條件的記錄,使查找成功,或直到子表不存在為止,此時查找不成功。1.3.4算法復雜度假設其數組長度為n,其算法復雜度為O(log(n)),下面提供一段二分查找實現的偽代碼:BinarySearch(max,min,des)mid-desthen此處程序正確嗎?max=mid-1elsemin=mid+1returnmax折半查找法也稱為二分查找法,它充分利用了元素間的次序關系,采用分治策略,可在最壞的情況下用O(logn)完成搜索任務。它的基本思想是,將n個元素分成個數大致相同的兩半,取a[n/2]與欲查找的x作比較,如果x=a[n/2]則找到x,算法終止。如果xa[n/2],則我們只要在數組a的右半部繼續(xù)搜索x。1.4分塊查找step1先選取各塊中的最大關鍵字構成一個索引表。step2查找分兩個部分:先對索引表進行二分查找或順序查找,以確定待查記錄在哪一塊中;然后,在已確定的塊中用順序法進行查找。1.4.1方法描述將n個數據元素"按塊有序"劃分為m塊(m≤n)。每一塊中的結點不必有序,但塊與塊之間必須"按塊有序";即第1塊中任一元素的關鍵字都必須小于第2塊中任一元素的關鍵字;而第2塊中任一元素又都必須小于第3塊中的任一元素,……1.4.2操作步驟step1先選取各塊中的最大關鍵字構成一個索引表。step2查找分兩個部分:先對索引表進行二分查找或順序查找,以確定待查記錄在哪一塊中;然后,在已確定的塊中用順序法進行查找。1.5哈希表查找1.5.1基本原理從此處開始至正文最后一頁的文字部分格式,按照如下格式設置:字體:正文宋體;字號:小四;段落中的格式為:正文:兩端對齊;首行縮進:2字符;間距:段前段后均為:0行;行距:1.5倍行距。具體圖示如下:代碼部分請仔細檢查正誤。然后按照上述正文設置格式以及代碼縮進格式調整。我們使用一個下標范圍比較大的數組來存儲元素??梢栽O計一個函數(哈希函數,也叫做散列函數),使得每個元素的關鍵字都與一個函數值(即數組下標)相對應,于是用這個數組單元來存儲這個元素;也可以簡單的理解為,按照關鍵字為每一個元素"分類",然后將這個元素存儲在相應"類"所對應的地方。但是,不能夠保證每個元素的關鍵字與函數值是一一對應的,因此極有可能出現對于不同的元素,卻計算出了相同的函數值,這樣就產生了"沖突",換句話說,就是把不同的元素分在了相同的"類"之中。后面我們將看到一種解決"沖突"的簡便做法。總的來說,"直接定址"與"解決沖突"是哈希表的兩大特點。1.5.2函數構造構造函數的常用方法(下面為了敘述簡潔,設h(k)表示關鍵字為k的元素所對應的函數值):1)除余法選擇一個適當的正整數p,令h(k)=kmodp
這里,p如果選取的是比較大的素數,效果比較好。而且此法非常容易實現,因此是最常用的方法。2)數字選擇法如果關鍵字的位數比較多,超過長整型范圍而無法直接運算,可以選擇其中數字分布比較均勻的若干位,所組成的新的值作為關鍵字或者直接作為函數值。1.5.3沖突處理線性重新散列技術易于實現且可以較好的達到目的。令數組元素個數為S,則當h(k)已經存儲了元素的時候,依次探查(h(k)+i)modS,i=1,2,3……,直到找到空的存儲單元為止(或者從頭到尾掃描一圈仍未發(fā)現空單元,這就是哈希表已經滿了,發(fā)生了錯誤。當然這是可以通過擴大數組范圍避免的)。1.5.4支持運算哈希表支持的運算主要有:初始化(makenull)、哈希函數值的運算(h(x))、插入元素(insert)、查找元素(member)。
設插入的元素的關鍵字為x,A為存儲的數組。
初始化比較容易,例如
constempty=maxlongint;//用非常大的整數代表這個位置沒有存儲元素
p=9997;//表的大小
proceduremakenull;
vari:integer;
begin
fori:=0top-1do
A:=empty;
End;哈希函數值的運算根據函數的不同而變化,例如除余法的一個例子:
functionh(x:longint):Integer;
begin
h:=xmodp;
end;我們注意到,插入和查找首先都需要對這個元素定位,即如果這個元素若存在,它應該存儲在什么位置,因此加入一個定位的函數locate
functionlocate(x:longint):integer;
varorig,i:integer;
begin
orig:=h(x);
i:=0;
while(ix)and(A[(orig+i)modS]empty)do
inc(i);
//當這個循環(huán)停下來時,要么找到一個空的存儲單元,要么找到這個元
//素存儲的單元,要么表已經滿了
locate:=(orig+i)modS;
end;
插入元素
procedureinsert(x:longint);
varposi:integer;
begin
posi:=locate(x);//定位函數的返回值
ifA[posi]=emptythenA[posi]:=x
elseerror;//error即為發(fā)生了錯誤,當然這是可以避免的
end;查找元素是否已經在表中
proceduremember(x:longint):boolean;
varposi:integer;
begin
posi:=locate(x);
ifA[posi]=xthenmember:=true
elsemember:=false;
end;2算法實現2.1順序查找在一個已知無(或有序)序隊列中找出與給定關鍵字相同的數的具體位置。原理是讓關鍵字與隊列中的數從最后一個開始逐個比較,直到找出與給定關鍵字相同的數為止,它的缺點是效率低下。2.1.1方法分類(1)Java實現方法packagesearch;/*順序查找*des要查找的元素*i保存當前元素的下標*/publicclassOrderSearch{publicstaticintordersearch(int[]arry,intdes){inti=0;for(;i<=arry.length-1;i++){if(des==arry[i])returni;}return-1;}publicstaticvoidmain(String[]args){int[]a=newint[]{2,3,5,6,7,3,};System.out.println(ordersearch(a,3));}}(2)C實現算法intsq_search(keytypekeyp[],intn,keytypekey){inti;for(i=0;i<n;i++)if(key[i]==key)returni;//查找成功return-1;//查找失敗}3)C++實現方法intSeqsch(ElemTypeA[],intn,KeyTypeK){//從順序表A的n個元素中順序查找關鍵字為K的元素,若成功返回其下標,否則返回-1inti;for(i=0;i<n;i++){if(A[i].key==K)break;}if(i<=n-1)//查找成功返回下標,否則返回-1returni;elsereturn-1;}4)php實現方法functionseq_sch($array,$n,$k){
for($i=0;$i<$n;$i++){
if($array[$i]==$k)
break;
}
if($i<$n){
return$i;
}else{
return-1;
}
}2.2二分查找2.2.1算法要求必須采用順序存儲結構2)必須按關鍵字大小有序排列。2.2.2算法復雜度假設其數組長度為n,其算法復雜度為o(log(n))下面提供一段二分查找實現的偽代碼:BinarySearch(max,min,des)mid-<(max+min)/2while(min<=max)mid=(min+max)/2ifmid=desthenreturnmidelseifmid>desthenmax=mid-1elsemin=mid+1returnmax折半查找法也稱為二分查找法,它充分利用了元素間的次序關系,采用分治策略,可在最壞的情況下用O(logn)完成搜索任務。它的基本思想是,將n個元素分成個數大致相同的兩半,取a[n/2]與欲查找的x作比較,如果x=a[n/2]則找到x,算法終止。如果x<a[n/2],則我們只要在數組a的左半部繼續(xù)搜索x(這里假設數組元素呈升序排列)。如果x>a[n/2],則我們只要在數組a的右半部繼續(xù)搜索x。2.2.3代碼示例1)Python源代碼123456789101112131415161718192021def
binarySearch(lists,select):
is_none=False
iflists!=[]:
cen_num=len(lists)/2
tlag=lists[cen_num]
gt_list=lists[0:cen_num]
lt_list=lists[cen_num+1:]
if
tlag==select:
is_none=True
return
is_noneelif
tlag>select:
is_se=binarySearch(gt_list,select)
if
notis_se:
return
binarySearch(lt_list,select)
return
is_none
elif
tlag<select:
is_se=binarySearch(lt_list,select)if
notis_se:
return
binarySearch(gt_list,select)return
is_none2)pascal源代碼1234567891011121314151617181920212223242526programjjzx(input,output);vara:array[1..10]ofinteger;i,j,n,x:integer;begin['輸入10個從小到大的數:']fori:=1to10doread(a[i]);['輸入要查找的數:']readln(x);i:=1;n:=10;j:=trunc((i+n)/2);repeatifa[j]>xthenbeginn:=j-1;j:=trunc((i+n)/2)endelseifa[j]<xthenbegini:=j+1;j:=trunc((j+n)/2)end;until(a[j]=x)or(i>=n);{為什么是這個結束循環(huán)條件}ifa[j]=xthenwriteln('查找成功!位置是:',j:3)elsewriteln('查找失敗,數組中無此元素!')end.PHP代碼實現3)C語言代碼123456789101112131415161718192021222324252627282930313233343536373839404142434445intBinSearch(SeqList*R,intn,KeyTypeK){//在有序表R[0..n-1]中進行二分查找,成功時返回結點的位置,失敗時返回-1intlow=0,high=n-1,mid;//置當前查找區(qū)間上、下界的初值while(low<=high){if(R[low].key==K)returnlow;if(R[high].key==k)returnhigh;//當前查找區(qū)間R[low..high]非空mid=low+((high-low)/2);//使用(low+high)/2會有整數溢出的問題//(問題會出現在當low+high的結果大于表達式結果類型所能表示的最大值時,//產生溢出后再/2是不會產生正確結果的,而low+((high-low)/2)不存在這個問題if(R[mid].key==K)returnmid;//查找成功返回if(R[mid].key<K)low=mid+1;//繼續(xù)在R[mid+1..high]中查找
elsehigh=mid-1;//繼續(xù)在R[low..mid-1]中查找
}if(low>high)return-1;//當low>high時表示所查找區(qū)間內沒有結果,查找失敗}//BinSeareh
上面代碼復雜難懂intbsearchWithoutRecursion(intarray[],intlow,inthigh,inttarget){while(low<=high){intmid=(low+high)/2;if(array[mid]>target)high=mid-1;elseif(array[mid]<target)low=mid+1;else//findthetargetreturnmid;}//thearraydoesnotcontainthetargetreturn-1;}2.2.4遞歸實現1234567891011121314intbinary_search(constintarr[],intlow,inthigh,intkey){intmid=low+(high-low)/2;if(low>high)return-1;else{if(arr[mid]==key)returnmid;elseif(arr[mid]>key)returnbinary_search(arr,low,mid-1,key);elsereturnbinary_search(arr,mid+1,high,key);}}1)Java代碼1234567891011121314151617public
static
int
binarySearch(Integer[]
srcArray,
int
des)
{
int
low
=
0;
int
high
=
srcArray.length
-
1;
while
((low
<=
high)
&&
(low
<=
srcArray.length
-
1)
&&
(high
<=
srcArray.length
-
1))
{
int
middle
=
low
+
((high
-
low)
>>
1);
if
(des
==
srcArray[middle])
{
return
middle;
}
else
if
(des
<
srcArray[middle])
{
high
=
middle
-
1;
}
else
{
low
=
middle
+
1;
}
}
return
-1;}2)AAuto代碼123456789101112131415161718192021222324252627282930//二分查找functionbinSearch(t,v){varp=#t;varp2;varb=0;do{p2=p;p=b+math.floor((p-b)/2)//二分折半運算if(p==b)return;if(t[p]<v){//判斷下限b=p;p=p2;}}while(t[p]>v)//判斷上限returnt[p]==v&&p;}//測試tab={}//創(chuàng)建數組,每個元素都是隨機數for(i=1;10;1){tab[i]=math.random(1,10000)}//插入一個已知數table.push(tab,5632)//排序table.sort(tab)io.open()io.print("數組",table.tostring(tab))io.print("使用二分查找,找到5632在位置:",binSearch(tab,5632))}3)PHP代碼12345678910111213141516171819202122232425262728293031//遞歸版本functionbin_sch($array,$low,$high,$k){if($low<=$high){$mid=intval(($low+$high)/2);
if($array[$mid]==$k){return$mid;}elseif($k<$array[$mid]){returnbin_sch($array,$low,$mid-1,$k);}else{returnbin_sch($array,$mid+1,$high,$k);}}return-1;}//非遞歸版本functionbinsearch($x,$a){$c=count($a);$lower=0;$high=$c-1;while($lower<=$high){$middle=intval(($lower+$high)/2);if($a[$middle]>$x)$high=$middle-1;elseif($a[$middle]<$x)$lower=$middle+1;elsereturn$middle;}return-1;}4)C++代碼1234567891011121314151617181920212223242526272829intbinSearch(constint*Array,intstart,intend,intkey){intleft,right;intmid;left=start;right=end;//注釋中為遞歸算法,執(zhí)行效率低,不推薦/*if(key<Array[mid]){return(binSearch(Array,left,mid,key));}elseif(key>Array[mid]){return(binSearch(Array,mid+1,right,key));}elsereturnmid;*/
while(left<=right){mid=(left+right)/2;if(key==Array[mid]){returnmid;}elseif(key<Array[mid]){right=mid-1;}elseif(key>Array[mid]){left=mid+1;}}return-1;}[1]
5)AS3代碼123456789101112131415publicstaticfunctionbinSearch(list:Array,low:int,high:int,key:int):int{if(low>high)return-1;varmid:int=low+int((high-low)/2);varindex:int=-1if(list[mid]==key){index=mid;}elseif(list[mid]<key){low=mid+1;index=binSearch(list,low,high,key);}else{high=mid-1;index=binSearch(list,low,high,key);}returnindex;}6)JavaScript代碼12345678910111213141516171819varArr=[3,5,6,7,9,12,15];functionbinary(find,arr,low,high){if(low<=high){if(arr[low]==find)returnlow;if(arr[high]==find)returnhigh;varmid=Math.ceil((high+low)/2);if(arr[mid]==find){returnmid;}elseif(arr[mid]>find){returnbinary(find,arr,low,mid-1);}else{returnbinary(find,arr,mid+1,high);}}return-1;}binary(15,Arr,0,Arr.length-1);7)PHP代碼123456789101112131415161718192021/*二分查找:前提,該數組已經是一個有序數組,必須先排序,再查找。*/functionbinarySearch(&$array,$findVal,$leftIndex,$rightIndex){$middleIndex=round(($rightIndex+$leftIndex)/2);if($leftIndex>$rightIndex){echo'查無此數<br/>';return;}if($findVal>$array[$middleIndex]){binarySearch($array,$findVal,$middleIndex+1,$rightIndex);}elseif($findVal<$array[$middleIndex]){binarySearch($array,$findVal,$leftIndex,$middleIndex-1);}else{echo"找到數據:index=$middleIndex;value=$array[$middleIndex]<br/>";if($array[$middleIndex+1]==$array[$middleIndex]&&$leftIndex<$rightIndex){binarySearch($array,$findVal,$middleIndex+1,$rightIndex);}if($array[$middleIndex-1]==$array[$middleIndex]&&$leftIndex<$rightIndex){binarySearch($array,$findVal,$leftIndex,$middleIndex-1);}}}2.3分塊查找2.3.1方法描述分塊查找要求把一個大的線性表分解成若干塊,每塊中的節(jié)點可以任意存放,但塊與塊之間必須排序。假設是按關鍵碼值非遞減的,那么這種塊與塊之間必須滿足已排序要求,實際上就是對于任意的i,第i塊中的所有節(jié)點的關鍵碼值都必須小于第i+1塊中的所有節(jié)點的關鍵碼值。此外,還要建立一個索引表,把每塊中的最大關鍵碼值作為索引表的關鍵碼值,按塊的順序存放到一個輔助數組中,顯然這個輔助數組是按關鍵碼值費遞減排序的。查找時,首先在索引表中進行查找,確定要找的節(jié)點所在的塊。由于索引表是排序的,因此,對索引表的查找可以采用順序查找或折半查找;然后,在相應的塊中采用順序查找,即可找到對應的節(jié)點。分塊查找在現實生活中也很常用。例如,一個學校有很多個班級,每個班級有幾十個學生。給定一個學生的學號,要求查找這個學生的相關資料。顯然,每個班級的學生檔案是分開存放的,沒有任何兩個班級的學生的學號是交叉重疊的,那么最好的查找方法實現確定這個學生所在的班級,然后再在這個學生所在班級的學生檔案中查找這個學生的資料。上述查找學生資料的過程,實際上就是一個典型的分塊查找。2.3.2操作步驟step1先選取各塊中的最大關鍵字構成一個索引表;[1]
step2查找分兩個部分:先對索引表進行二分查找,順序查找,以確定待查記錄在哪一塊中;然后,在已確定的塊中用順序法進行查找。在C語言中其代碼如下:#include<stdio.h>structindex/*定義塊的結構*/{intkey;intstart;intend;}index_table[4];/*定義結構體數組*/intblock_search(intkey,inta[])/*自定義實現分塊查找*/{inti,j;i=1;while(i<=3&&key>index_table[i].key)/*確定在那個塊中*/i++;if(i>3)/*大于分得的塊數,則返回0*/return0;j=index_table[i].start;/*j等于塊范圍的起始值*/while(j<=index_table[i].end&&a[j]!=key)/*在確定的塊內進行查找*/j++;if(j>index_table[i].end)/*如果大于塊范圍的結束值,則說明沒有要查找的數,j置0*/j=0;returnj;}main(){inti,j=0,k,key,a[16];printf("pleaseinputthenumber:\n");for(i=1;i<16;i++)scanf("%d",&a[i]);/*輸入由小到大的15個數*/for(i=1;i<=3;i++){index_table[i].start=j+1;/*確定每個塊范圍的起始值*/j=j+1;index_table[i].end=j+4;/*確定每個塊范圍的結束值*/j=j+4;index_table[i].key=a[j];/*確定每個塊范圍中元素的最大值*/}printf("pleaseinputthenumberwhichdoyouwanttosearch:\n");scanf("%d",&key);/*輸入要查詢的數值*/k=block_search(key,a);/*調用函數進行查找*/if(k!=0)printf("success.thepositionis:%d\n",k);/*如果找到該數,則輸出其位置*/elseprintf("nofound!");/*若未找到則輸出提示信息*/}2.4哈希表查找2.4.1操作步驟step1取數據元素的關鍵字key,計算其哈希函數值。若該地址對應的存儲空間還沒有被占用,則將該元素存入;否則執(zhí)行step2解決沖突。step2根據選擇的沖突處理方法,計算關鍵字key的下一個存儲地址。若下一個存儲地址仍被占用,則繼續(xù)執(zhí)行step2,直到找到能用的存儲地址為止。哈希查找步驟為:設哈希表為HST[0~M-1],哈希函數取H(key),解決沖突的方法為R(x);Step1對給定k值,計算哈希地址Di=H(k);若HST為空,則查找失??;若HST=k,則查找成功;否則,執(zhí)行step2(處理沖突)。Step2重復計算處理沖突的下一個存儲地址Dk=R(Dk-1),直到HST[Dk]為空,或HST[Dk]=k為止。若HST[Dk]=K,則查找成功,否則查找失敗。哈希查找的本質是先將數據映射成它的哈希值。哈希查找的核心是構造一個哈希函數,它將原來直觀、整潔的數據映射為看上去似乎是隨機的一些整數。哈希查找的產生有這樣一種背景——有些數據本身是無法排序的(如圖像),有些數據是很難比較的(如圖像)。如果數據本身是無法排序的,就不能對它們進行比較查找。如果數據是很難比較的,即使采用折半查找,要比較的次數也是非常多的。因此,哈希查找并不查找數據本身,而是先將數據映射為一個整數(它的哈希值),并將哈希值相同的數據存放在同一個位置一即以哈希值為索引構造一個數組。在哈希查找的過程中,只需先將要查找的數據映射為它的哈希值,然后查找具有這個哈希值的數據,這就大大減少了查找次數。如果構造哈希函數的參數經過精心設計,內存空間也足以存放哈希表,查找一個數據元素所需的比較次數基本上就接近于一次。2.4.2解決沖突影響哈希查找效率的一個重要因素是哈希函數本身。當兩個不同的數據元素的哈希值相同時,就會發(fā)生沖突。為減少發(fā)生沖突的可能性,哈希函數應該將數據盡可能分散地映射到哈希表的每一個表項中。解決沖突的方法有以下兩種:1)開放地址法如果兩個數據元素的哈希值相同,則在哈希表中為后插入的數據元素另外選擇一個表項。當程序查找哈希表時,如果沒有在第一個對應的哈希表項中找到符合查找要求的數據元素,程序就會繼續(xù)往后查找,直到找到一個符合查找要求的數據元素,或者遇到一個空的表項。2)鏈地址法將哈希值相同的數據元素存放在一個鏈表中,在查找哈希表的過程中,當查找到這個鏈表時,必須采用線性查找方法。3)一個簡單的哈希查找算法程序1:#include<stdlib.h>2:#include<string.h>3:#include"list.h"4:#include"hash.h"5:6:#defineHASH_SIZE10247:8:staticlistnode_t*hashTable[HASH_SIZE];9:10:voidinsert(constchar*s)11:{12:listnode_t*ele=newNode((void*)s)13:unsignedinth=hash(s)%HASH_SIZE;14:15:ele->next=hashTable[h]16:hashTable[h]=ele;17:}18:19:voidprint(void)20:{21:inth;22:23:for(h=0;h<HASH_SIZE;h++)24:{25:listnode_t*lp=hashTalbe[h];26:27:if(lp==NULL)28:continue;29:printf("[%d]",h);30:while(lp)31:{32:printf("\t'%s'",lp->u.str)33:lp=ip->next;34:}35:putchar('\n');36:}37:}38:39:constchar*search(constchar*s)40:{39:unsignedinth=hash(s)%HASH_SIZE;42:listnode_t*lp=hashTable[h];43:44:while(lp)45:{46:if(!strcmp(s,lp->u.str))47:returnlp->u.str;48:lp=lp->next;49:}50:returnNULL;51:}3比較與總結3.1分類查找的依據查找的目的在于從一些數據中尋找一個特定的值,這看似簡單的工作之所以產生了形形色色的各種方法,無非都是為了追求更高的效率與更方便的操作。在范圍較小的時候,無論采取什么方法查找,所花費的時間都相差無幾,在這種情況下,算法上簡單易行,且對存儲格式要求較低的線性查找無疑就可以滿足我們的要求。但當所要查找的范圍達到了一定程度時,這種方法在耗時上的弱點就逐漸突顯,比如我們想在一本字典中查找一個英文單詞,如果一頁一頁一詞一詞地去搜索,顯然是極為愚蠢的。通常,我們會采取這樣的方法,比如我們想查找“nature”這個詞,一翻字典翻到了前綴為“m”的部分,我們就會往后翻幾頁,一看翻過了,到了前綴為“o”的部分,就又往會翻幾頁,這樣我們很快就縮小了查找的范圍,并能找到想查單詞的精確位置。這種方法在查找范圍較大時比較可行,但是它要求所要查找的數據必須按照一定的順序排列,比如字典中的單詞,如果在字母順序上不呈現一定的規(guī)律性,這種方法就無從談起了。這種方式的查找根據數據的分布規(guī)律不同還可以有更細的方法分支,其中最簡單和典型的是折半查找,此外還有Fibonacci查找(又稱費氏查找),插補查找等,其實都可以算是準折半查找,只是“半”的概念有所不同罷了。另外,在數據源變動頻繁的情況下,還可以使用二叉查找樹來存儲數據。當數據量更大,即使用這種方法也要很多次查找才能確定精確的位置時,我們又想到可以用某種公式將一個有某一特征的數據放在一個固定的位置,需要查找時只需直接用公式計算出它的所在位置就可以引用,這就是雜湊查找。這種方法在查找時間上的效率已趨于極限,但是很難找到一個恰到好處的公式使得數據按這種格式存放時不產生空隙,所以這種方法對于空間的要求就多一些。3.2效率比較
下表總結出這三類查找方式的特點,可以看出,沒有哪一種方式是絕對的好或不好的,根據具體的問題和環(huán)境,選用最適合的方式,方能得到最佳的效率。表1效率比較查找方式對數據存儲空間的要求對數據存儲格式的要求查找時間復雜度順序查找低無高二分查找低按照一定順序存儲中哈希表查找高數據和位置間根據一定的關系建立映射低參考文獻[1]/[Z].[2]機械工業(yè)出版社,2013年1月:32-150.這是什么書啊?作者和數名呢?格式參照下面兩個文獻的書寫。[3]嚴蔚敏,吳偉民.數據結構[M].清華大學出版社,北京.1992.[4]吉根林,陳波.擻據結構教程[M].電子工業(yè)出版社,北京.2009.說明采用五級分制,即2.評語內容包括:學術價值、實際意義、達到水平、學術觀點及論證有無錯誤等?;贑8051F單片機直流電動機反饋控制系統(tǒng)的設計與研究基于單片機的嵌入式Web服務器的研究MOTOROLA單片機MC68HC(8)05PV8/A內嵌EEPROM的工藝和制程方法及對良率的影響研究基于模糊控制的電阻釬焊單片機溫度控制系統(tǒng)的研制基于MCS-51系列單片機的通用控制模塊的研究基于單片機實現的供暖系統(tǒng)最佳啟停自校正(STR)調節(jié)器單片機控制的二級倒立擺系統(tǒng)的研究基于增強型51系列單片機的TCP/IP協(xié)議棧的實現基于單片機的蓄電池自動監(jiān)測系統(tǒng)基于32位嵌入式單片機系統(tǒng)的圖像采集與處理技術的研究基于單片機的作物營養(yǎng)診斷專家系統(tǒng)的研究基于單片機的交流伺服電機運動控制系統(tǒng)研究與開發(fā)基于單片機的泵管內壁硬度測試儀的研制基于單片機的自動找平控制系統(tǒng)研究基于C8051F040單片機的嵌入式系統(tǒng)開發(fā)基于單片機的液壓動力系統(tǒng)狀態(tài)監(jiān)測儀開發(fā)模糊Smith智能控制方法的研究及其單片機實現一種基于單片機的軸快流CO〈,2〉激光器的手持控制面板的研制基于雙單片機沖床數控系統(tǒng)的研究基于CYGNAL單片機的在線間歇式濁度儀的研制基于單片機的噴油泵試驗臺控制器的研制基于單片機的軟起動器的研究和設計基于單片機控制的高速快走絲電火花線切割機床短循環(huán)走絲方式研究基于單片機的機電產品控制系統(tǒng)開發(fā)基于PIC單片機的智能手機充電器基于單片機的實時內核設計及其應用研究基于單片機的遠程抄表系統(tǒng)的設計與研究基于單片機的煙氣二氧化硫濃度檢測儀的研制基于微型光譜儀的單片機系統(tǒng)單片機系統(tǒng)軟件構件開發(fā)的技術研究基于單片機的液體點滴速度自動檢測儀的研制基于單片機系統(tǒng)的多功能溫度測量儀的研制基于PIC單片機的電能采集終端的設計和應用基于單片機的光纖光柵解調儀的研制氣壓式線性摩擦焊機單片機控制系統(tǒng)的研制基于單片機的數字磁通門傳感器基于單片機的旋轉變壓器-數字轉換器的研究基于單片機的光纖Bragg光柵解調系統(tǒng)的研究單片機控制的便攜式多功能乳腺治療儀的研制基于C8051F020單片機的多生理信號檢測儀基于單片機的電機運動控制系統(tǒng)設計Pico專用單片機核的可測性設計研究基于MCS-51單片機的熱量計基于雙單片機的智能遙測微型氣象站MCS-51單片機構建機器人的實踐研究基于單片機的輪軌力檢測基于單片機的GPS定位儀的研究與實現基于單片機的電液伺服控制系統(tǒng)用于單片機系統(tǒng)的MMC卡文件系統(tǒng)研制基于單片機的時控和計數系統(tǒng)性能優(yōu)化的研究基于單片機和CPLD的粗光柵位移測量系統(tǒng)研究單片機控制的后備式方波UPS提升高職學生單片機應用能力的探究基于單片機控制的自動低頻減載裝置研究基于單片機控制的水下焊接電源的研究基于單片機的多通道數據采集系統(tǒng)基于uPSD3234單片機的氚表面污染測量儀的研制基于單片機的紅外測油儀的研究96系列單片機仿真器研究與設計基于單片機的單晶金剛石刀具刃磨設備的數控改造基于單片機的溫度智能控制系統(tǒng)的設計與實現基于MSP430單片機的電梯門機控制器的研制基于單片機的氣體測漏儀的研究基于三菱M16C/6N系列單片機的CAN/USB協(xié)議轉換器基于單片機和DSP的變壓器油色譜在線監(jiān)測技術研究基于單片機的膛壁溫度報警系統(tǒng)設計基于AVR單片機的低壓無功補償控制器的設計基于單片機船舶電力推進電機監(jiān)測系統(tǒng)基于單片機網絡的振動信號的采集系統(tǒng)基于單片機的大容量數據存儲技術的應用研究基于單片機的疊圖機研究與教學方法實踐基于單片機嵌入式Web服務器技術的研究及實現基于AT89S52單片機的通用數據采集系統(tǒng)基于單片機的多道脈沖幅度分析儀研究機器人旋轉電弧傳感角焊縫跟蹤單片機控制系統(tǒng)基于單片機的控制系統(tǒng)在PLC虛擬教學實驗中的應用研究基于單片機系統(tǒng)的網絡通信研究與應用基于PIC16F877單片機的莫爾斯碼自動譯碼系統(tǒng)設計與研究基于單片機的模糊控制器在工業(yè)電阻爐上的應用研究基于雙單片機沖床數控系統(tǒng)的研究與開發(fā)基于Cygnal單片機的μC/OS-Ⅱ的研究基于單片機的一體化智能差示掃描量熱儀系統(tǒng)研究基于TCP/IP協(xié)議的單片機與Internet互聯的研究與實現變頻調速液壓電梯單片機控制器的研究基于單片機γ-免疫計數器自動換樣功能的研究與實現基于單片機的倒立擺控制系統(tǒng)設計與實現單片機嵌入式以太網防盜報警系統(tǒng)基于51單片機的嵌入式Internet系統(tǒng)的設計與實現單片機監(jiān)測系統(tǒng)在擠壓機上的應用MSP430單片機在智能水表系統(tǒng)上的研究與應用基于單片機的嵌入式系統(tǒng)中TCP/IP協(xié)議棧的實現與應用單片機在高樓恒壓供水系統(tǒng)中的應用基于ATmega16單片機的流量控制器的開發(fā)基于MSP430單片機的遠程抄表系統(tǒng)及智能網絡水表的設計基于MSP430單片機具有數據存儲與回放功能的嵌入式電子血壓計的設計基于單片機的氨分解率檢測系統(tǒng)的研究與開發(fā)鍋爐的單片機控制系統(tǒng)基于單片機控制的電磁振動式播種控制系統(tǒng)的設計基于單片機技術的WDR-01型聚氨酯導熱系數測試儀的研制一種RISC結構8位單片機的設計與實現基于單片機的公寓用電智能管理系統(tǒng)設計基于單片機的溫度測控系統(tǒng)在溫室大棚中的設計與實現基于MSP430單片機的數字化超聲電源的研制基于ADμC841單片機的防爆軟起動綜合控制器的研究基于單片機控制的井下低爆綜合保護系統(tǒng)的設計基于單片機的空調器故障診斷系統(tǒng)的設計研究單片機實現的尋呼機編碼器單片機實現的魯棒MRACS及其在液壓系統(tǒng)中的應用研究自適應控制的單片機實現方法及基上隅角瓦斯積聚處理中的應用研究基于單片機的鍋爐智能控制器的設計與研究超精密機床床身隔振的單片機主動控制PIC單片機在空調中的應用單片機控制力矩加載控制系統(tǒng)的研究項目論證,項目可行性研究報告,可行性研究報告,項目推廣,項目研究報告,項目設計,項目建議書,項目可研報告,本文檔支持完整下載,支持任意編輯!選擇我們,選擇成功!項目論證,項目可行性研究報告,可行性研究報告,項目推廣,項目研究報告,項目設計,項目建議書,項目可研報告,本文檔支持完整下載,支持任意編輯!選擇我們,選擇成功!單片機論文,畢業(yè)設計,畢業(yè)論文,單片機設計,碩士論文,研究生論文,單片機研究論文,單片機設計論文,優(yōu)秀畢業(yè)論文,畢業(yè)論文設計,畢
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 合肥新房購房合同范本
- 關于大學生學生會工作總結報告
- 先裝修付款合同范例
- 中學聯盟浙江省紹興縣楊汛橋鎮(zhèn)中學人教版七年級歷史與社會上冊教學設計《3-3-3 水上都市》
- 出租檳榔合同范例
- 大學生年終總結夢
- 合股協(xié)議合同范本
- 合同范例與格式條款
- 農資化肥合同范例
- 供冷合同范例
- 電動車 - 新能源汽車電機驅動系統(tǒng)拆裝
- 南充市高2025屆高三高考適應性考試(二診)生物試卷(含答案)
- 2025年雙方共同離婚協(xié)議書樣本
- 2025年鐘山職業(yè)技術學院單招職業(yè)技能測試題庫往年題考
- 2025版七年級下冊歷史必背知識點
- TSG21-2025固定式壓力容器安全技術(送審稿)
- 《苗圃生產與管理》教案-第一章 園林苗圃的建立
- 2025年眼藥水項目投資分析及可行性報告
- 2025年內蒙古自治區(qū)政府工作報告測試題及參考答案
- 2024年全國中學生生物學聯賽試題及答案詳解
- 《中藥注射劑大全》課件
評論
0/150
提交評論