算法與數據結構(三)線性表的查找算法


基礎:查找的基本概念

查找表:由同一類數據元素構成的集合。(線性表、數表、散列表)

關鍵字:是數據元素中某個數據項的值,用它可以表示一個數據元素。(主關鍵字:唯一地標識;次關鍵字:不唯一地標識)

查找:根據制定的某個值,在查找表中確定一個其關鍵字等於給定的這個值的數據元素

動態/靜態查找:查表的同時改表成為動態查找,反之為靜態查找

平均查找長度:ASL=∑PiCi (i=1,2,3,…,n),Pi 為查找表中第i個數據元素的概率,Ci為找到第i個數據元素時已經比較過的次數。

*線性表的查找*

(1)順序查找

(2)二分查找(折半查找)

(3)分塊查找

(1)順序查找

從表的一端開始,依次將記錄的關鍵字與給定的值進行比較。

順序查找既適用於順序存儲結構(數組),又適用於鏈式存儲結構(鏈表),以下介紹順序存儲結構:

數據元素的類型:

 

1 typedef struct{ 2  KeyType key; 3  InfoType otherinfo 4 }ElemType
1 typedef struct { 2           ElemType   *R; //表基址
3           int    length;     //表長
4 }SSTable;

代碼:

1 int LocateELem(SqList L,ElemType e) 2 {  for (i=0;i< L.length;i++) 3         if (L.elem[i]==e) return i+1; 4     return 0; 5 }

改進:把待查關鍵字key存入表頭(“哨兵”),從后向前逐個比較,可免去查找過程中每一步都要檢測是否查找完畢,加快速度。

1 int Search_Seq( SSTable ST , KeyType key ){ 2    //若成功返回其位置信息,否則返回0
3     ST.R[0].key =key; 4     for( i=ST.length; ST.R[ i ].key!=key;  - - i ); 5  //不用for(i=n; i>0; - -i) 或 for(i=1; i<=n; i++) 
6             return i; 7 }

順序查找的性能分析:

空間復雜度:一個輔助空間。

時間復雜度:

1) 查找成功時的平均查找長度 設表中各記錄查找概率相等 ASLs(n)=(1+2+ ... +n)/n =(n+1)/2

2)查找不成功時的平均查找長度 ASLf =n+1

(2)二分查找

例:找“21”:

 

 

若k==R[mid].key,查找成功

若k<R[mid].key,則high=mid-1

若k>R[mid].key,則low=mid+1

代碼:(迭代)

 

 1  int Search_Bin(SSTable ST,KeyType key){
 2      low=1;high=ST.length;//若找到,則函數值為該元素在表中的位置,否則為0 
 3      while(low<=high){
 4            mid=(low+high)/2;
 5            if(key==ST.R[mid].key) return mid; 
 6            else if(key<ST.R[mid].key) high=mid-1;//前一子表查找
 7            else low=mid+1;                               //后一子表查找
 8      }                                        
 9      return 0;        //表中不存在待查元素
10 }       

 

*需要特別注意的是循環執行的條件是:low<=high,而不是low<high,因為low=high時,還要比較最后一個元素。

代碼:(遞歸)

1 int Search_Bin (SSTable ST, keyType key, int low, int high) 2 { 3   if(low>high) return 0;   //查找不到時返回0 
4   mid=(low+high)/2; 5   if(key等於ST.elem[mid].key)  return mid; 6   else if(key小於ST.elem[mid].key) 7     ……..//遞歸
8   else…….  //遞歸
9 } 

二分查找的性能分析——判定樹

若所有結點的空指針域設置為一個指向一個方形結點的指針,稱方形結點為判定樹的外部結點;對應的,圓形結點為內部結點

查找成功時的平均查找長度:ASL=1/11*(1*1+2×2+4×3+4*4 )=33/11=3

查找成功時比較次數:為該結點在判定樹上的層次數,不超過樹的深度 d = [log2n] + 1 查找不成功的過程就是走了一條從根結點到外部結點的路徑d或d-1。

二分查找的性能分析:

查找過程:每次將待查記錄所在區間縮小一半,比順序查找效率高,時間復雜度O(log2 n)

適用條件:采用順序存儲結構的有序表,不宜用於鏈式結構

(3)分塊查找

分塊有序,即分成若干子表,要求每個子表中的數值都比后一塊中數值小(但子表內部未必有序)。 然后將各子表中的最大關鍵字構成一個索引表,表中還要包含每個子表的起始地址(即頭指針)。

① 對索引表使用折半查找法(因為索引表是有序表);

② 確定了待查關鍵字所在的子表后,在子表內采用順序查找法(因為各子表內部是無序表);

查找效率:ASL=Lb+Lw(Lb:對索引表查找的ASL;Lw:對塊內查找的ASL)

分塊查找的性能分析:

優點:插入和刪除比較容易,無需進行大量移動。

缺點:要增加一個索引表的存儲空間並對初始索引表進行排序運算。

適用情況:如果線性表既要快速查找又經常動態變化,則可采用分塊查找。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM