一、 查找概念
假設有兩組數據:
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. 順序表查找算法
順序查找算法:
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. 順序表查找優化//比較次數減少
改進后的順序查找算法
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. 折半查找
折半查找前提是順序存儲,記錄有序。
思想:與記錄中間值比較,如果比中間值小去左邊查,否則去右邊查找,直到找到為止,區域內沒記錄時查找失敗。
算法:
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 意味着失敗*/ }
這兩種查找方式的主要區別:
- 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); }