算例1
-
题目描述
-
解题思路
①常规的题目,只需要用数组即可解决
-
解题代码
#include <stdio.h>
int main() {
int buf[200];
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 0; i < n;i++) {
scanf("%d", &buf[i]);
} //输入数据
int x, ans = -1; //初始化答案为-1,以期在找不到答案时能正确的输出-1
scanf("%d", &x);
for (int i = 0; i < n;i++) { //依次遍历数组元素
if (x == buf[i]) { // 目标数字与数组元素依次比较
ans = i;
break; //找到答案后跳出循环
}
}
printf("%d\n", ans);
}
return 0;
}
-
注意点
①在满足时空要求的前提下,用线性遍历即可
算例2
-
题目描述
-
解题思路
①线性查找的时间复杂度在O(L),而二分查找的时间复杂度在O(logL)
②1000 x 10000 千万级已经超过了规定的时间复杂度,故不可以使用遍历查找
-
解题代吗
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
struct Student { //用于表示学生个体的结构体
char no[100]; //学号
char name[100]; //姓名
int age; //年龄
char sex[5]; //性别
bool operator < (const Student & A) const { //重载小于运算符使其能使用sort函数排序
return strcmp(no, A.no) < 0;
}
}buf[1000];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 0; i < n;i++) {
scanf("%s%s%s%d",
buf[i].no, buf[i].name, buf[i].sex, &buf[i].age);
} //输入
sort(buf, buf + n); //对数组排序使其按照学号升序排列
int t;
scanf("%d", &t); //有t组询问
while (t-- != 0) { //while 循环保证查询次数为t
int ans = -1; //目标元素下标,初始化为-1
char x[30];
scanf("%s", x); //待查找学号
int top = n - 1, base = 0; //初试时,开始下标0,结束下标n-1,查找子集为整个数组
while (top >= base) { //当查找子集不为空集时重复二分查找
int mid = (top + base) / 2; //计算中间点下标
int tmp = strcmp(buf[mid].no, x); //比较中间点学号与目标学号
if (tmp == 0) {
ans = mid;
break; //若相等,则查找完成跳出二分查找
}
else if (tmp > 0) top = mid - 1; // 若大于,则结束下标变为中间点前一个点下标
else base = mid + 1; //若小于,则开始点下标变为中间点后一个点坐标
}
if (ans == -1) { //若查找失败
printf("No Answer!\n");
}
else printf("%s %s %s %d\n",
buf[ans].no, buf[ans].name, buf[ans].sex, buf[ans].age); //若查找成功
}
}
return 0;
}
-
注意点
①运用二分查找之后,时间复杂度被优化到O(nlogn+m*logn)
②也可以使用cmp函数进行排序(重载是个好东西)
bool cmp(Stu a, Stu b) {
return a.id < b.id;
}
//····
sort(buf,buf+n,cmp);
③二分法查找还有一个非常重要的功能:定界。试思考下面问题:
算法思路:
// 存在一个升序有序的数组buf,其大小为size,目标数字为target
int base = 0, top = size; //初始情况与二分查找一致
while (base <= top) { //二分循环条件与二分查找一致
int mid = (base + top) / 2;
if (buf[mid] <= target) base = mid + 1; //符合前一部分数字规定
else top = mid - 1; //否则
}
int ans = top; //最后,top即为我们要求的数字数组下标,buf[top] 为该数字本身