查找是在一些(有序/无序)的数据元素中通过一定的方法找出与给定关键字相同的数据元素。

无序查找

最简单的无序查找为:

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;
}