基础算法(排序、二分、精度运算)

编程入门 行业动态 更新时间:2024-10-26 06:32:52

基础算法(排序、二分、<a href=https://www.elefans.com/category/jswz/34/1769184.html style=精度运算)"/>

基础算法(排序、二分、精度运算)

这里写目录标题

  • 排序
    • 快速排序
      • 主要思想
      • 解法
      • 其它细节
    • 归并
      • 主要思想
      • 解法
    • STL - sort
    • 总结时间效率
  • 二分
    • 整数二分
      • 主要思想
      • 解法
      • 举例:
        • 起始位置
        • 结束位置
    • 浮点数二分
      • 解法
    • 二级目录
  • 一级目录
    • 二级目录
    • 二级目录
    • 二级目录
  • 一级目录
    • 二级目录
    • 二级目录
    • 二级目录
  • 一级目录
    • 二级目录
    • 二级目录
    • 二级目录

排序

快速排序

主要思想

解法

1、暴力

开辟新数组 遍历之后 将小的放在一个数组里 大的放在一个数组里 最后将两个数组合并到总数组里

2、双指针

i在左边 j在右边 二者同时向中间移动 但i的值大于等于x时 就停下 j的值小于等于x时 就停下 两个都停下之后 交换两个的值 之后 两者再次同时向中间移动 然后继续这个过程 直到i到了j的右边(或者说j 到了i 的左边)

模板:

main函数中 第一次调用模板时 传入 0 n-1(也就是两个边界的下标)因为是向函数传入左右边界值以供使用 参数就是 l r

模版就是那个quick_sort函数
第一行是判断边界 如果里面没有数 或者只有一个数 那么直接return

之后选定left为分界点 之后初始化i 和 j的位置

然后在while循环里 进行do … while 循环
第一个do i++;while (q[i]<x)意思是只要q[i]<x 那么就会一直在这一行执行 也就是i会一直++
第二个就是 只要满足 q[j]>x 那么就会让j–

之后再判断(i<j)交换 i j 所指向的数据 因为只有上面两个do … while跳出 才能到if 所以这里是指 i j 都停下了 进行if判断并交换 符合解题逻辑

最后递归 依次递归左边区间以及右边区间 以 j 为分界点
quick_sort(q,l,j);
quick_sort(q,j+1,r);

(注意 当递归时传入j时 (例如第一个递归的第三个参数)上面的int x后面必须是q【l】 一定不可以是r)

其它细节


这个表示一百万 100 0000 + 10
所以一百万就是 1e6
+10 是因为预留一些空间 防止越界


根据题目的数据范围 来定义数组的大小

归并

主要思想



首先是两个有序的序列数组 从小到大排列 之后两个指针依次指向两个数组的最小值 也就是最左端 然后比较两个指针的值 将较小值放入res数组 然后谁放入了res 谁的指针后移一位 之后 再次比较 直到某个指针到了最后 那么进行完这次比较之后 将另一个没有比完的数组 依次接在res的最后

当两个数相同时 一般是让第一个序列的指针所指的数放入res

快排以及归并的时间复杂度 都是n*log n

解法

模板:

首先传入q 0 n-1 也就是数组 左边界 右边界

之后在merge_sort函数里面

第一行 判断边界

之后确定分界点 使用 l + r / 2 可以写成 l + r >> 1 这样更快一些

紧接着就分成两个数组 递归调用 以mid为分界点 l mid 以及 mid+1 r

之后 开始合并 首先要定义一个k 用来记录tmp数组的下标 之后i指向l j指向mid+1 也就是都指向两个数组的第一个位置
while循环:当i j 都没出去最后时 循环继续 if 选出较小值 放入临时数组tmp
当第一个循环结束 进入第二个循环 这时 已经有其中一个数组比较完了 所以 就判断是谁还有值 将剩下的值拼接到tmp数组后面即可

最终for循环 将tmp数组的数赋值回q数组 因为最后输出的是q数组 如果不想赋值 直接该输出函数是tmp即可

STL - sort

#include

传入两个指针 指向第一个元素以及最后一个元素 用数组名代替首元素指着 之后q+n指向了最后一个元素

总结时间效率


快速排序 归并排序 STL-sort 三者时间差不多

二分

整数二分

主要思想


图中两个指针所指的点 可以认为是两个目标点 左边是红色区间边界点 右边是黄色区间的边界点
假如要找红色的那个点 那么就是第一种情况 首先让mid = r + l >> 1
之后 看mid是否满足在红色区间 如果在 那么目标值红点在mid右边 所以mid左边可以丢掉 但是mid不能丢掉 因为mid在有效区间内 所以 L = mid

如果mid不满足在红色区间 那么目标值在mid左边 并且mid在绿色区间 不可能取到目标值 所以直接丢掉mid右边以及mid r=mid-1

然后这个就是下面“解法一栏”的第二个模板 看到 L=mid的更新 就回过头把mid改成 r+l +1 >> 1

假如要找绿色区间边界点 简称绿点 也就是把绿点当做目标值 首先让mid= r + l >> 1
之后 看mid是否满足绿色区间 如果满足 那么目标值在mid左边 那么 更新r=mid
else mid在红色区间 目标值在mid右边 更新 l = mid +1

解法

模板:

思考过程
首先 先写mid = l + r >> 1
之后写check()函数 或者直接判断也可以 总之要有一个判断mid在目标值左还是右
之后看满足第一种情况还是第二种
如果是更新了 l=mid 那么回过头来修改mid 在mid的分子上 + 1
如果是更新了 r=mid 那么就无需修改mid

举例:


这里让找每个查询元素的起始位置以及终止位置 那么 我们这里只看某一个查询元素即可

起始位置


首先来找起始位置:
对于一个x 假设我们定性质为 >=x
这样就符合找绿点的情况

最外层while是指m个查询 所以循环体里就是一个查询的代码
目标值用一个变量表示 因为一般都是程序来输入目标值 我们来查找

首先 初始化 l 和 r 的位置 分别是 0 n-1
之后while(l<r)循环条件是l<r 因为当l = r时 就是要找的值
在小循环里 首先定义mid
之后因为要查询绿点 所以 q[mid] >= x
如果为真 那么 r = mid
else l = mid + 1

结束位置

之后找右边坐标 可以理解为右边界


这里插播一下无解的情况 如果最后的结果不是x (如果不是 那么q【l】的值就是>x的第一个值 ) 那么就是无解 直接返回无解的值

这里就是找红点的情况
首先check就是q【mid】<=x 更新 l = mid
else r = mid - 1
这里看到更新的是 l = mid
所以回去修改mid = r + l + 1 >> 1

最后输出 l 其实输出 l 还是 r 都一样 因为 循环最后跳出的条件就是 l = r

浮点数二分

解法



这里无需考虑边界问题 当设定的条件是 mid在目标值右边 更新r = mid
否则 更新 l = mid

循环条件:
如果要求输出六位小数 那么循环条件是 r - l > 1e-8
如果要求输出四位小数 那么循环条件是 r - l > 1e-6

二级目录

一级目录

二级目录

二级目录

二级目录

一级目录

二级目录

二级目录

二级目录

一级目录

二级目录

二级目录

二级目录

更多推荐

基础算法(排序、二分、精度运算)

本文发布于:2023-11-16 06:56:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1614094.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:精度   算法   基础

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!