线性查找O(n)
-
线性查找
题目描述:
输入
输入有多组数据。
每组输入n,然后输入n个整数,再输入m,然后再输入m个整数(1<=m,n<=100)。输出
如果在n个数组中输出YES否则输出NO。
样例输入
5
1 5 2 4 3
3
2 5 6样例输出
YES
YES
NO解法思路
代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int arr[100];
bool Lineserch(int n,int target){
//线性查找函数
bool flag=false; //设置标志位,如果没找到,则一直保持为false
for(int i=0;i<n;++i){
//遍历查找
if(arr[i]==target){
flag=true; //找到后直接跳出循环
break;
}
}
return flag;
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&arr[i]);
}
int m;
scanf("%d",&m);
for(int i=0;i<m;++i){
int target; //遍历接收查找目标
scanf("%d",&target);
if(Lineserch(n,target)){
//如果排序算法返回true则打印YES
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}
二分查找
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int arr[100];
bool binarysearch(int n,int target){
//二分查找
int low=0; //设置low,high
int high=n-1;
while(low<=high){
//low走到high右边则结束
int mid=low+(high-low)/2; //根据每次的low,high计算mid
if(arr[mid]>target){
//去mid左边找
high=mid-1;
}else if(arr[mid]<target){
//去mid右边找
low=mid+1;
}else{
return true;
}
}
return false;
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&arr[i]);
}
sort(arr,arr+n); //切记二分是基于有序序列的,所以要先排序
int m;
scanf("%d",&m);
for(int i=0;i<m;++i){
int target;
scanf("%d",&target);
if(binarysearch(n,target)){
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}
-
使用系统自带的实现二分查找
题目描述:
输入
输出
样例输入
5
1 5 2 4 3
3
2 5 6样例输出
YES
YES
NO解法思路
使用lower_bound和upper_bound
- lower_bound返回大于或等于目标值的第一个位置
- upper_bound返回大于目标值的第一个位置
- 例如:
1. 1 2 4 4 5 8 10 22,target=4,则返回lower_bound=4(第一个4),upper_bound=5
2. 1 2 4 4 5 8 10 22,target=7,则返回lower_bound=8,upper_bound=8
3. 1 2 4 4 5 8 10 22,target=30,则返回lower_bound=22后一个位置, upper_bound=22后一个位置(目标值比所有元素都大)
代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int arr[100];
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&arr[i]);
}
sort(arr,arr+n); //切记二分是基于有序序列的,所以要先排序
int m;
scanf("%d",&m);
for(int i=0;i<m;++i){
int target;
scanf("%d",&target);
int position=lower_bound(arr,arr+n,target)-arr; //lower_bound(首地址,尾地址,查找目标)会返回
// 1.目标值地址
// 2.比目标值大的第一个数的地址
// 3.数组中下标n地址(最后一个位置的后一个)
//而且返回的是这个地址,并不是下标,所以要减去首地址arr,就是下标了
if(position!=n&&arr[position]==target){
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}
散列查找
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int arr[100]; //获取待排序列
bool Hashtable[1000000]; //哈希表
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&arr[i]);
Hashtable[arr[i]]= true; //⭐获取到待排值后,将哈希表中相应的下标置为true
}
int m;
scanf("%d",&m);
for(int i=0;i<m;++i){
int target;
scanf("%d",&target);
if(Hashtable[target]){
//target对于下标在哈希表中为true
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
int arr[100]; //获取待排序列
unordered_map<int,bool>Hashtable; //⭐使用系统再带的散列表:unordered_map<一对映射的数据类型>哈希表名字
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&arr[i]);
Hashtable[arr[i]]= true; //获取到待排值后,将哈希表中相应的下标置为true
}
int m;
scanf("%d",&m);
for(int i=0;i<m;++i){
int target;
scanf("%d",&target);
if(Hashtable[target]){
//target对于下标在哈希表中为true
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}