數據結構-靜態查找表


 

 

 

一、  查找概念

假設有兩組數據:

int array1[]={6,4,5,3,8,7,1,2,0,9};

int array2[]={0,1,2,3,4,5,6,7,8,9};

一個有序數組,一個無序數組, 在他們之間查找某一個值的方法有什么區別呢,

對於兩組數據我們都可以用最直接的方法,逐個比較直到遇到合適的值。

思路是怎么樣的呢:從表中最后一個記錄開始,逐個進行記錄的關鍵字和給定值的比較,若某個記錄的關鍵字和給定值比較相等,則返回返回記錄所在的位置,或查找完所有記錄后還沒有發現符合的記錄,則查找失敗。我們稱其為順序查找。

當數據是一個有序的情況時,我們可以利用這樣一種思路:當記錄的key按關系有序時可以使用折半查找

對於給定key值,逐步確定待查記錄所在區間,每次將搜索空間減少一半(折半), 直到查找成功或失敗為止。我們稱其為折半查找。

若要利用計算機幫助我們實現查找的過程,就需要我們了解查找的相關知識.

查找:查詢(Searching)特定元素是否在表中。

查找表:由同一類型的數據元素(或記錄)構成的集合。

查找成功:若表中存在特定元素,稱查找成功,應輸出該記錄;

查找失敗:否則,稱查找不成功(也應輸出失敗標志或失敗位置)。

靜態查找表:只查找,不改變集合內的數據元素。

動態查找表:既查找,又改變(增減)集合內的數據元素。

關鍵字:記錄中某個數據項的值,可用來識別一個記錄。

主關鍵字:可以唯一標識一個記錄的關鍵字。例如:學號

次關鍵字:識別若干記錄的關鍵字。例如:女

二、  順序表查找

   順序查找( Linear search,又稱線性查找 )用逐一比較的辦法順序查找關鍵字,這顯然是最直接的辦法。

  1. 1.        順序表查找算法

順序查找算法:

int Search_Seq( int  *a , int n,int  key )
{
for( i=1;i<=n;  i++)
{
            if(key==a[i])
{
                return i;
}
}
      return 0;
} 

這里元素都放在數組下標為1的地方開始,返回0意味着查找失敗,比較的時候只要注意key的數據類型就可以了。

  1. 1.        順序表查找優化//比較次數減少

改進后的順序查找算法

int Search_Seq( int  *a , int n,int  key )
{
     int i=n;     //指向表尾部
     a[0]=key;   //把待查記錄放在a[0]中做監視哨
while(a[i]!=key)
{
   i--;
}
return i;    /*返回0 意味着失敗*/
} 

這里免去數組越界的判斷,從末端開始查找,當數據記錄較多的時候能夠大大的提高效率,可以注意這種編程技巧。

1.        順序查找的平均查找長度

 

順序查找平均查找長度(ASL  Average Search Length),假設查找的表中有n個元素,查找每個元素的概率相等,那么查找第一個元素的次數是1次,查找第二個元素的次數是2次,以此類推查找第n個元素的次數是n次。則總的查找次數為:1+2+3+...+n。這是一個等差數列,求得和后為(1+n*n/2;再由於n種情況的概率一樣,則平均起來計算為

因此得到順序查找的平均查找長度的結論是: (n+1)/2。

一、  有序表查找

  1. 1.        折半查找

折半查找前提是順序存儲,記錄有序。

思想:與記錄中間值比較,如果比中間值小去左邊查,否則去右邊查找,直到找到為止,區域內沒記錄時查找失敗。

算法:

int Binary_Search( int  *a , int n,int  key )
{
     int low,high,mid;
     low=1;
     high=n;
while(low<=high)
{
        mid=(low+high)/2;   //定位中間的記錄 
        if(key<a[mid])
            high=mid-1;    //小於中間記錄high移到mid左邊即mid-1
else if(key>a[mid])
            low=mid+1;    //大於中間記錄high移到mid右邊即mid+1
else
        return mid;
}
return 0;    /*返回0 意味着失敗*/
}

這兩種查找方式的主要區別:

 

  1. 2.        折半查找的平均查找長度

折半查找的平均查找長度分析:由於折半查找算法的特點,沒次會拋棄約一半的數據,在剩余一半里繼續使用折半查找,因此每次都是前一次的約一半的關系。則可以得出折半查找的平均查找長度約為log2n ,記為:

 代碼折半查找

/* Note:Your choice is C IDE */
#include "stdio.h"
int  binarysearch(int a[],int c){
    int low,high,mid;
    high=14;
    low=0;
    while(low<=high){
        mid=(low+high)/2;
        if(a[mid]>c){
        high=mid-1;
        }else if(a[mid]<c){
        low=mid+1;
        }else{
        return mid;
        }
    }
    return-1; 
}
void main()
{
    int a[]={1,2,4,5,8,9,12,15,18,25,36,42,52,62,85};
    int c;
    scanf("%d",&c);
    printf("%d\n",binarysearch(a,c));
}

代碼-字符定位

#include "stdio.h"
#include "string.h"
int sort(char s[],char sb[],int sta){//sta 為開始查找處
    int i=sta,j=0;
    while(i<(strlen(s))&&j<strlen(sb)){
        if(s[i]==sb[j])
        {
            i++;
            j++;
        }else{
           i=i-j+1;//將開始往后移
           j=0;
        }
    }
    if(j==strlen(sb)){
        return i-strlen(sb);
    }else{
    return -1;}
    }
void main()
{
    int sta=0,len,o;
    char sb[20];
    char s[100]="theanswertoyourkuestionisyes";
    printf("輸入字符串:");
    scanf("%s",sb);
    fflush(stdin);
    o=sort(s,sb,sta);
    printf("%d",o);
}

 


免責聲明!

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



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