【上机训练】查找

线性查找O(n)

  1. 线性查找

    题目描述:

    输入

    输入有多组数据。
    每组输入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;
}

二分查找

  1. 自己实现二分查找

    题目描述:

    输入

    输出

    样例输入

    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 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;
}
  1. 使用系统自带的实现二分查找

    题目描述:

    输入

    输出

    样例输入

    5
    1 5 2 4 3
    3
    2 5 6

    样例输出

    YES
    YES
    NO

    解法思路

    使用lower_boundupper_bound

    1. lower_bound返回大于或等于目标值的第一个位置
    2. upper_bound返回大于目标值的第一个位置
    3. 例如:
      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;
}

散列查找

  1. 自己实现散列查找

    题目描述:

    输入

    输出

    样例输入

    样例输出

    1322830052

    解法思路

    h(value)=index
    更直接的方式:h(value)=value,值等于几,就存在哪里

    代码

#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;
}
  1. 系统自带的哈希表

    题目描述:

    输入

    输出

    样例输入

    样例输出

    解法思路

    unordered_map

    代码

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

猜你喜欢

转载自blog.csdn.net/Qmilumilu/article/details/114810429
今日推荐