靜態查找表的總結

一、順序查找表

1.順序查找表:
順序查找的過程爲:從表的一端開始掃描,逐個進行記錄的關鍵字和給定值的比較,若某個記錄的關鍵字和給定值比較相等,則查找成功,找到所查記錄;反之,若直至表的另一端,其關鍵字和給定值比較都不等,則表明表中沒有所查記錄,查找不成功。

2 . 算法分析:
(1) 在最壞的情況下,順序查找需要比較 n 次,即 MSL = n 。
(2) 最好的情況是第一個元素即爲目標元素,最壞情況是最後一個元素爲目標元素,平均情況是與線性表中一半的元素比較。
(3) 假定各記錄的查找機會均等,即 P i = 1/n ,由於查找第 i 個記錄需要比較 i 次,即 C i = i ,於是有:
ASL = (n+1)/2;
這樣,最大查找長度和平均查找長度的數量級 ( 即算法的時間複雜度 ) 均爲 O(n)

3 . 順序查找的優點和缺點:
優點:該算法比較簡單且適用面比較廣,它對錶的結構無任何要求,無論記錄是否按關鍵字有序均可應用。
缺點:平均查找長度比較大,特別是當n值很大時查找效率較低。

4.算法實現_C++:

#include<iostream>
using namespace std;
typedef struct node{
    int date[100];
}LinkNode

int main(){
LinkNode p;
int i,n,schar,set = 0;
cout<<"請輸入要輸入多少個數據"<<endl;
cin>>n;

cout<<"請往表中輸入數據"<<endl;
for(i=0;i<n;i++){
    cin>>p.date[i];
}

cout<<"請輸入您要查找的數據"<<endl;
cin>>schar;

for(i=0;i<n;i++){
    if(p.date[i] == schar){
    cout<<"您要查找的數據存在表中"<<endl;
    set == 1;
    break;
}
}

if(set == 0){
cout<<"您要查找的數據表中不存在"<<endl;
}
}

二、有序表的查找(二分查找)

1.二分查找表:
對於以數組方式存貯的記錄,如果數組中各個記錄的次序是按其關鍵字值的大小順序排列的,則稱爲有序數組或有序表。形如:05 13 19 21 37 56 64 80。 對有序表採用二分查找。

2.查找過程:
首先將待查找的k值和有序表R中間的位置 mid=(low+high)/2上關鍵字進行比較:
(1) 若相等,則查找成功;
(2) 若R[mid].key>k,則說明待查找的結點在表的前半部分,可縮小範圍,在表的前半部分[low,mid-1]繼續進行二分查找;
(3) 若R[mid].key< k,則說明待查找的結點在表的後半部分,可縮小範圍,在表的後半部分[mid+1,high]繼續進行二分查找;
這樣經過一次關鍵字的比較就縮小一半的查找區間;如此反覆,直到找到關鍵字爲k的結點(查找成功),或當前的查找區間爲空(查找失敗)。

3.平均查找長度:
折半查找的過程實際上是從二叉樹的根結點開始到該記錄結點的查找過程。因此,比較的次數不超過二叉樹的深度 d = [log2 n ] + 1 。特別地,當 n = 2 d -1 時,描述折半查找的二叉樹一定是深度爲 d 的滿二叉樹。查找第 1 層 ( 根結點 ) 的記錄僅需一次比較,且只有一個記錄。查找第 i 層 (1 ≤ i < d) 記錄需做 i 次比較,第 i 層有 2 i-1 個記錄。假定每個記錄的查找概率相等,即 P i = 1/n ,則平均查找長度爲:
ASL = Ci*Pi=1/n(C1+C2+C3+…..)=1/n(1+2*2+3*22+…+(d-1)*2d-2+d*L)式中, L 爲葉結點個數, 1 ≤ L ≤ 2d-1 , n = 2d-1-1+L。
當n較大(n>50)時,可有下列近似的結果,ASL=log2(n+1)-1
  所以,折半查找的平均查找長度數量級 ( 算法時間複雜度 ) 亦爲 O (log2 n )
(詳見《數據結構(C語言版)》嚴蔚敏,第220頁)

4.算法分析_C:

int BinSearch(table R[], int n, KeyType k){
         int low,high,mid;
          low = 1; high = n;
         while(low<=high){
           mid = (low+high)/2;
         if(k == R[mid].key)
           return mid;
         if(k > R[mid].key)
           high = mid + 1;
         else 
           low = mid + 1;
        }
}

5.二分查找的優缺點:
優點:查找效率高,查找速度快,比較次數少,平均性能好;
缺點:待查表必須爲已經排好序的有序表,並且要用順序表做爲存儲結構,插入刪除較困難。

因此,二分查找特別適用於那種一經建立就很少改動、而又經常需要查找的線性表。對那些查找少而又經常需要改動的線性表,可採用鏈表作存儲結構,進行順序查找。鏈表上無法實現二分查找。

三、索引順序表查找(分塊查找)

1.分塊查找
分塊查找又稱索引順序查找,是一種介於順序查找和二分查找之間的查找方法。 分塊查找要求將查找表分成 若干個子表,並對子表建立索引表,查找表的每一個子表由索引表中的索引項確定。索引項包括兩個字段:關鍵碼字段(存放對應子表中的最大關鍵碼值) ;指針字段(存放指向對 應子表的指針) ,並且要求索引項按關鍵碼字段有序。查找時,先用給定值key 在索引表中 檢測索引項,以確定所要進行的查找在查找表中的查找分塊(由於索引項按關鍵碼字段有序,可用順序查找或折半查找) ,然後,再對該分塊進行順序查找。

這裏寫圖片描述

2 查找過程:
分塊查找的函數分爲如下兩步:
a)首先確定待查找的結點屬於哪一塊,即查找所在的塊;(順序查找或分塊查找均可)
b)然後,在塊內查找要查的結點。(順序查找)

設表共n個結點,分b塊,s=n/b
(分塊查找索引表)平均查找長度=Log2(n/s+1)+s/2
(順序查找索引表)平均查找長度=(S2+2S+n)/(2S)

3.優缺點分析:
優點:在表中插入或刪除一個記錄時,只要找到該記錄所屬的塊,就在該塊中進行插入或刪除運算。因塊內記錄的存放是任意的,所以,插入或刪除比較容易,無需移動大量記錄。效率大於順序查找,小於二分查找。
缺點:主要代價是需要增加一個輔助數組存儲索引表和對初始表進行分塊排序建立索引表的運算。

4.算法實現_C++:

#include<iostream>  
using namespace std;  

#define MAX 16  

typedef int key_type;  

struct elem  
{  
    key_type key; //關鍵字   
};  

//索引結構   
struct index           
{  
    key_type key; //索引值   
    long low;     //起始位置   
    long high;    //終止位置   
};  

int index_search(elem e[], key_type key, int n, index idx[], int idx_length)  
{  
    int low = 0;  
    int high = idx_length - 1;  
    int mid;  

    //採用折半查找在索引表裏找到關鍵字所在的塊  
    while(low <= high)  
    {  
        mid = (low + high)/2;  
        if(key < idx[mid].key)  
            high = mid - 1;  
        else if(key > idx[mid].key)  
            low = mid + 1;  
             else  
            break;  
    }   

    //採用順序查找的方法從塊中查找關鍵值  
    int i = idx[mid].low;  

    while(i <= idx[mid].high && e[i].key != key)  
    {  
        i++;  
    }   

    if(i > idx[mid].high)  
        return -1;  
    else  
        return i;  
}  


int main(int argc, char** argv)  
{  
    elem linelist[MAX] = {  
        8, 20, 13, 17,  
        40, 42, 45, 32,  
        49, 58, 50, 52,  
        67, 79, 78, 80  
    };  

    int n = sizeof(linelist) / sizeof(elem);  
    key_type key = 50;  

    //建立索引表  
    index index_table[4] = {{20,0,3}, {45,4,7}, {58,8,11}, {80,12,15}};   
    int idx_length = sizeof(index_table) / sizeof(index);  

    printf("線性表中的元素爲:\n");  

    int i = 0;  

    while(i < n)   
    {  
        printf("%d\n",linelist[i].key);  
        i++;  
    }  

    printf("\n關鍵字[%d]在線性表中的位置下標爲[%d]", key, index_search(linelist, key, n, index_table, idx_length));  

    getchar();  
    system("pause");  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章