首页 > 其他分享 >chapter3-排序和查找2

chapter3-排序和查找2

时间:2024-02-15 13:22:19浏览次数:34  
标签:排序 int bound chapter3 查找 MAXN include 散列

2.基础查找

所谓查找,就是在查找空间中找寻符合要求的解的过程。查找方法有多种,下面简单介绍3种。不同的策略对查找的效率和结果有不同的影响。

2.1 线性查找

从首元素开始,遍历整个序列,直到找到目标元素,则结束算法;或者遍历完序列还没有匹配,则查找失败结束算法。时间复杂度为O(n)
linearsearch.jpg

线性查找
//基础查找-线性查找 2024-02-15
#include <iostream>
#include <cstdio>

using namespace std;

const int MAXN = 100 + 10;
int arr[MAXN];

//线性查找
bool LinearSearch(int n, int target)
{
    for(int i=0; i<n; i++)
    {
        if(target == arr[i])
            return true;
    }
    return false;
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &arr[i]);
    }
    int m, target;
    scanf("%d", &m);
    for(int i=0; i<m; i++)
    {
        scanf("%d", &target);
        if(LinearSearch(n, target))
        {
            printf("YES\n");
        }
        else{
            printf("NO\n");
        }
    }
    return 0;
}

2.2 二分查找

二分查找的前提是有序序列。有两种方法,一种是自定义,自己写一个函数用来贴合题面的要求;第二种是内定义,即使用C++内部封装好的函数来实现二分查找。时间复杂度为O(logn)

2.2.1 自定义

定义两个变量L和R分别指向首元素和序列的尾元素,计算middle,如果middle所指向的元素和要找的目标值target相等,则查找成功,结束算法;否则如果middle所指向的元素比target小,则在右半边继续查找;左半边同理;直至查找到目标值,或者当R<L时算法结束,查找失败。
binarysearch.jpg

二分查找_自定义
//基础查找-二分查找-前提序列有序-自定义 2024-02-15
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 100 + 10;
int arr[MAXN];

bool BinarySearch(int n, int target)
{
    int left = 0;
    int right = n-1;
    while(left <= right)
    {
        int middle = left + (right - left)/2;
        if(arr[middle] == target)
        {
            return true;
        }
        else if(arr[middle] < target)//搜索右半部分
        {
            left = middle + 1;
        }
        else{
            right = middle -1;
        }
    }
    return false;
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &arr[i]);
    }
    sort(arr, arr+n);//默认compare升序
    int m, target;
    scanf("%d", &m);
    for(int i=0; i<m; i++)
    {
        scanf("%d", &target);
        if(BinarySearch(n, target))
        {
            printf("YES\n");
        }
        else{
            printf("NO\n");
        }
    }
    return 0;
}

2.2.2 内定义

C++内部封装了两个用于实现二分查找的函数,即lower_bound和upper_bound。需要引用头文件#include <algorithm>

1、lower_bound:返回大于或等于目标值的第一个位置。
2、upper_bound:返回大于目标值的第一个位置。

内定义二分查找.jpg
lower_bound(first, last, target)有三个参数,分别是有序序列的起始地址、结束地址和目标值,target可为任意数据类型。
注意考虑lower_bound在查找目标值时的3种情况。其一如上图所示;其二是有序序列中没有目标值,lower_bound会返回最靠近目标值而大于目标值的元素的下标;其三,要查找的target值大于有序序列的最大值,此时lower_bound会移出序列,指向下标n,即越界访问。

注意:lower_bound函数返回的不是数组元素的下标,而是元素所在的地址,减去数组起始地址,即可得到数组下标。int position = lower_bound(arr, arr+n, target) - arr;

二分查找_内定义
//基础查找-二分查找-前提序列有序-内定义 2024-02-15
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 100 + 10;
int arr[MAXN];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &arr[i]);
    }
    sort(arr, arr+n);//默认compare升序
    int m, target;
    scanf("%d", &m);
    for(int i=0; i<m; i++)
    {
        scanf("%d", &target);
        int position = lower_bound(arr, arr + n, target) - arr ;
        if(position != n && arr[position] == target)
        {
            printf("YES\n");
        }
        else{
            printf("NO\n");
        }
    }
    return 0;
}

2.3 散列查找

线性查找和二分查找都是以数组下标为索引,去遍历查找target值,而散列查找使用散列函数,使得元素值经过常数时间的Hash函数计算后,直接得到其下标索引。时间复杂度为O(1)。
散列查找也有两种方法,一种是自定义,一种是内定义

hash.jpg

2.3.1 自定义

这里散列函数搞一个最简单的线性映射,即开一个和数据范围一样大的bool型辅助数组,在输入元素时,给对应的辅助数组赋值为true。未得到赋值的默认为false。

散列查找_自定义
//基础查找-散列查找 2024-02-15
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 100 + 10;
const int RANGE = 1e6;
int arr[MAXN];
bool hashTable[RANGE];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &arr[i]);
        hashTable[arr[i]] = true;
    }
    sort(arr, arr+n);//默认compare升序
    int m, target;
    scanf("%d", &m);
    for(int i=0; i<m; i++)
    {
        scanf("%d", &target);
        if(hashTable[target])
        {
            printf("YES\n");
        }
        else{
            printf("NO\n");
        }
    }
    return 0;
}

2.3.2 内定义

C++内部封装了散列函数unordered_map,需要引用头文件#include <unordered_map>

散列查找_内定义
//基础查找-散列查找-内定义 2024-02-15
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>

using namespace std;

const int MAXN = 100 + 10;

int arr[MAXN];
unordered_map<int, bool> hashTable;//1:元素的类型;2:是否出现过用bool表示
//相当于定义了一个辅助数组用于线性映射,就是散列函数
int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &arr[i]);
        hashTable[arr[i]] = true;
    }
    sort(arr, arr+n);//默认compare升序
    int m, target;
    scanf("%d", &m);
    for(int i=0; i<m; i++)
    {
        scanf("%d", &target);
        if(hashTable[target])
        {
            printf("YES\n");
        }
        else{
            printf("NO\n");
        }
    }
    return 0;
}

3.参考资料

1.C++ upper_bound()函数
2.rgb颜色对照表

标签:排序,int,bound,chapter3,查找,MAXN,include,散列
From: https://www.cnblogs.com/paopaotangzu/p/18015581

相关文章

  • 拓扑排序入门
    目录写在前面一些概念算法步骤字典序最大/最小的拓扑序列?模板例题3704.排队家谱树奖金P1983[NOIP2013普及组]车站分级1639.拓扑顺序写在前面昨晚cfdiv3的F就是一道基本上可以说板子的拓扑排序的题目,没有做出来感觉图论很早之前就看了,但是基本没有刷过什么题,开始补一下图论......
  • 912.排序数组--插入排序
    1.题目介绍给你一个整数数组nums,请你将该数组升序排列。示例1:输入:nums=[5,2,3,1]输出:[1,2,3,5]示例2:输入:nums=[5,1,1,2,0,0]输出:[0,0,1,1,2,5]2.题解2.1插入排序思路主要思路就是创建一个有序区域和无序区域,不断从无序区域取一张出来顺序插入有序区域即可代......
  • 912.排序数组--冒泡排序
    1.题目介绍给你一个整数数组nums,请你将该数组升序排列。示例1:输入:nums=[5,2,3,1]输出:[1,2,3,5]示例2:输入:nums=[5,1,1,2,0,0]输出:[0,0,1,1,2,5]2.题解2.1冒泡排序思路跟选择排序,固定一个i,后续者不断打擂台挑战不同,冒泡排序永远是两个邻接值比较,较大值不断向后冒......
  • 912.排序数组--选择排序
    1.题目介绍给你一个整数数组nums,请你将该数组升序排列。示例1:输入:nums=[5,2,3,1]输出:[1,2,3,5]示例2:输入:nums=[5,1,1,2,0,0]输出:[0,0,1,1,2,5]2.题解2.1插入排序思路打擂台,每次确定第一名,第二名,第三名,依次往后代码#include<bits/stdc++.h>usingnamespace......
  • Linux 目录磁盘满了,怎么查找大文件
    在Linux系统中,如果你的根目录(/)磁盘满了,你可以使用以下方法来查找占用空间最大的文件和目录。使用du(磁盘使用)命令来查找占用空间最大的目录:sudodu-h/--max-depth=1|sort-h这个命令会列出根目录下每个一级子目录的大小,并通过sort命令进行排序,-h标志表示“人类可读”的......
  • 排序
    一、选择排序voidselection_sort(int*arr,intL,intR){for(inti=L;i<R;i++){intind=i;for(intj=i+1;j<R;j++)if(arr[j]<arr[ind])ind=j;swap(arr[i],arr[ind]);}}二、插入排序......
  • 排序(待填充)
    题目描述为了快速地把修罗王和邪狼从混乱的队伍中找出来,典狱长准备对排队的囚犯进行从小到大的按编号排序,但是他不知道用哪一种排序方法最合适,因此他准备请教前来协助的高级魔法师张琪曼和楚继光。输入共两行,第一行为一个数N(N≤100000),即排队的总人数,第二行为N个数,即每......
  • 【算法】排序
    冒泡排序思想:每一轮确定一个最大值移到最右边。点击查看代码for(inti=n;i>=1;i--){ for(intj=1;j<i;j++){ if(a[j]>a[j+1])swap(a[j],a[j+1]); } }选择排序思想:与冒泡相似。点击查看代码for(inti=n;i>=1;i--){ intmax_id......
  • 各大排序的模板
    1.冒泡排序 1for(i=n;i>=1;--i)2{3for(j=1;j<=i;++j)4{5if(a[j]>a[j+1])6{7swap(a[j],a[j+1]);8}9}10}   2.快速排序1.懒人函数 1sort(a+1,a+n+1);   2.正常的1vo......
  • 补基础题(排序)
    2299--Ultra-QuickSort(poj.org)#include<iostream>//归并排序#include<cstring>usingnamespacestd;typedeflonglongll;constintN=500010;inta[N],tmp[N],ans;voidmerge_(lll,llmid,llr){inti=l,j=mid+1,t=0;while(i<=mid&......