查找是在一些(有序/无序)的数据元素中通过一定的方法找出与给定关键字相同的数据元素。
无序查找
最简单的无序查找为:
1 2 3 4 5 6 7 8
| int sq_find(int arr[], int n, int key){ for(int i = 0; i < n; i++){ if(arr[i] == key) return i; } return -1; }
|
对于这个for循环查找,一般的时间浪费在了i<n的边界检查上了,因此可以设置一个监视哨兵来优化无序查找:
1 2 3 4 5 6 7 8
| int sq_find(int arr[], int n, int key){
int i = n; arr[0] = key; while(arr[i] != key) i--; return i; }
|
有序查找
二分查找
非递归实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| int BiSearch(int arr[], const int num, int begin, int end){ int mid; if(begin > end){ return -1; }
while(begin <= end){ mid = (begin+end) / 2; if(num[mid] == num){ return mid; }else if(arr[mid] < num){ begin = mid + 1; }else if(arr[mid] > num){ end = mid - 1; } } return -1; }
|
递归实现
1 2 3 4 5 6 7 8 9 10 11 12
| int BiSearch(int arr[], const int num, int begin, int end){ int mid = -1; mid = (begin + end) / 2; if(num == arr[mid]){ return mid; }else if(num < arr[mid]){ return BiSearch(arr, num, begin, mid-1); }else if(num > arr[mid]){ return BiSearch(arr, num, mid+1, end); } return -1; }
|
分块查找
分块查找又叫索引顺序查找,是介于顺序查找与二分查找之间的一种查找方法。在二分查找中要求数据按关键字排序且有序,这一条件下在数目很大且动态变化的情况下很难满足,而分块查找优化了这种条件下的查找。
分块查找需要建立索引表,索引表是分段有序的,而数据集合可以使无序的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| struct indexBlock{ int max; int start; int end; }indexblock[4];
int blockSearch(int key, int a[]){ int i = 0; int j;
while(i<3 && key>indexblock[i].max) i++;
if(i >= 3) return -1;
j = indexblock[i].start;
while(j<=indexblock[i].end && a[j] != key) j++;
if(j > indexblock[i].end) j = -1;
return j; }
|