目录
搜索1
搜索:就是在数据集合中寻找给定的关键字的位置或判断其有无。
基本的搜索算法有如下三种,分别为线性搜索,二分搜索,散列法。
下面我们先学习前两者。
线性搜索
线性搜索就是从头顺次访问各元素,检查该元素是否与目标值相等。
线性搜索的算法效率很低,但是用于各种形式的数据。
普通的线性搜索:
int linesearch() {
for (int i = 0; i < n; i++) {
if (a[i] == key)return i;
else return 0;
}
}
添加标记的线性搜索:
int linesearch() {
int i=0;
a[n] = key;
while (a[i] != key)i++;
if (i == n)return 0;
return i;
}
向线性搜索中添加标记,可以将算法的效率提高常数倍。
标记:就是在数组等数据结构中设置一个拥有特殊值的元素,来达到简化循环控制等诸多目的。
在线性搜索中把含有目标关键字的数据放在数组末尾,用作标记。将原来的两个比较运算(一个循环,一个比较)变成一个不等价运算。线性搜索的算法复杂度为O(n),但在引入标记后能够提升常数倍。
示例
示例:出入包含n各整数的数列S以及包含q个整数的数列T,输出S和T中相同证书的个数C。
输入:第一行输入n,第二行输入S,第三行输入q,第四行输入T。
输出:一行输出C。
完整答案:
#include<stdio.h>
int a[100], key, n;
int linesearch(int a[],int n,int key) {
int i=0;
a[n] = key;
while (a[i] != key)i++;
if (i == n)return 0;
return 1;
}
int main() {
int i, n, q, key, sum = 0;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
scanf("%d", &q);
for (i = 0; i < q; i++) {
scanf("%d", &key);
if (linesearch(a, n, key))sum++;
}
printf("%d", sum);
return 0;
}
二分搜索
假设有一个包含n个元素的数组a,我们运用二分搜索在其中寻找key,其关键的代码如下:
int binarysearch(int a[],int key) {
int left = 0;
int right = n;
int mid;
while (left < right) {
mid = (left + right) / 2;
if (a[mid] == key)return 1;
else if (a[mid] > key)right = mid;
else left = mid + 1;
}
return 0;
}
在使用二分搜索时,要保证数据按升序排列(或者排序之后再使用二分搜索)。left指向搜索范围开头的元素,right指向末尾元素的后一位。
示例
示例:出入包含n各整数的数列S以及包含q个整数的数列T,输出S和T中相同证书的个数C。
输入:第一行输入n,第二行输入S(按升序排列),第三行输入q,第四行输入T。
输出:一行输出C。
与上面例题不同的地方在于S按升序排列,适合用二分搜索。
完整答案:
#include<stdio.h>
int n;
int binarysearch(int a[],int key) {
int left = 0;
int right = n;
int mid;
while (left < right) {
mid = (left + right) / 2;
if (a[mid] == key)return 1;
else if (a[mid] > key)right = mid;
else left = mid + 1;
}
return 0;
}
int main() {
int a[100], key, i, q;
int sum = 0;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
scanf("%d", &q);
for (i = 0; i < q; i++) {
scanf("%d", &key);
if (binarysearch(a, key))sum++;
}
printf("%d", sum);
return 0;
}
总结
对含有n个元素的数组执行线性搜索和二分搜索时,最坏的情况下的比较运算的次数分别如下表示:
元素数 | 线性搜索 | 二分搜索 |
100 | 100 | 7 |
10000 | 10000 | 14 |
100000 | 100000 | 20 |
线性搜索最坏的情况下要比较n次,而二分搜索大概需要次。遇到无序的数据时,只要进行一次排序,就可以套用二分搜索了。不过考虑到数据的体积,绝大多数情况下都需要用到高等排序算法。
读《挑战程序设计竞赛》第八天 (侵删)2021.2.26
( 2021.7.8 第一次修改)