减治法在查找算法中的应用

快速查找:选择问题是求一个n个数列表的第k个最小元素的问题,这个数k被称为顺序统计量。对于k=1或k=n来说,这并没有什么意义,我们通常会要找出这样的元素:该元素比列表中一半元素大,比另一半元素小,这样的元素被称为中值。我们当然可以对列表进行排序,之后找出对应下标的值,但是!!!这样一个查找问题,反而要对整个列表排序,是不是有点多余了呢?

这里引入划分的概念我们可以标定一个枢轴(任意元素,一般为首个元素),使得左半部分元素均小于枢轴,右半部分均大于枢轴。划分的方法由两种,Lomuto划分和Hoare划分。这里仅介绍Lomuto。

我们假设有一个数组a[0, n-1],其子数组为a[l, r](0 <= l <= r <= n-1),假定首个元素为枢轴p,将该数组分为三段,顺序放在p之后,依次为,第一段[元素小于p],第二段[元素大于等于p],第三段[尚未处理元素]。算法开始时前两段均为空。

从i = l+1开始,从左到右扫描子数组a[l, r],将第三段的首个元素与p比较,若a[i]>=p,执行i+1,这就相当于将a[i]划入了第二段,同时缩小了第三段;若a[i]<p,需要将s+1(s始终指向第一段的末位元素),同时交换a[i]与a[s],之后i+1。直到第三段为空,交换a[p]与a[s]。

下图为Lomuto划分示意图:

熟悉快速排序的读者估计看出来了,这就是快速排序中的一部分函数,只不过没有接触过Lomuto这种叫法而已。

当然,我们这里使用的方法就是快速选择(“快速”这一方法一开始并非用于排序,而是查找),下面给出查找第k小元素的代码:

public class Main {static int[] a= {89, 45, 68, 90, 29, 34, 17};static int k = 2;public static void main(String[] args) {System.out.println(fastsort(0, a.length-1, k));for (int i = 0; i < a.length; i++) {System.out.print(a[i] + " ");}}private static int Lomuto(int l, int r) {int p = a[l];int s = l;for (int i = l+1; i <= r; i++) {if (a[i] < p) {s = s+1;int temp = a[s];a[s] = a[i];a[i] = temp;}}int temp = a[l];a[l] = a[s];a[s] = temp;return s;}private static int fastsort(int l, int r, int k) {int s = Lomuto(l, r);/*** s在划分之后变成了枢轴所在的位置下标,如果s=k,输出a[s]* 这里要写成l+k-1,如果划分到右侧,只写k会出问题* */if (s == l + k - 1) {return a[s];}else if (s > l + k - 1){return fastsort(l, s-1, k);} else {return fastsort(s+1, r, l+k-1-s);}}
}

不幸的是,这样的算法时间复杂度为O(n^2),比之前基于排序的方法实际上更糟糕,但是分析表明,这种方法的平均情况下效率是线性的。而且基于划分的算法不仅可以查找第k小的元素,还可以给出列表中k个最小元素和n-k个最大元素。

减治法在查找算法中的应用(JAVA)--快速查找相关推荐

  1. 减治法在排序算法中的应用(JAVA)--插入排序

    一.减治法在排序算法中的应用 插入排序:时间复杂度O(n^2),虽然和选择.冒泡在最坏的情况下时间复杂度相同,但是插排平均性能在比自身的最差性能快一倍,所以相比选择.冒泡来说,插排要领先于二者. pu ...

  2. 减治法在查找算法中的应用(JAVA)--二叉查找树的查找、插入、删除

    减治法在查找算法中的应用 二叉查找树的查找与插入: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于或等于它的根节点的值: (2)若右子树不空, ...

  3. 减治法在查找算法中的应用(JAVA)--折半查找

    减治法在查找算法中的应用 折半查找:(时间复杂度O(log以2为底n的对数)) 对于有序数组的查找来说,折半查找是一种非常高效的算法,其基本原理为:比较查找键k和数组中间元素a[m],如果相等,算法结 ...

  4. 分治法在排序算法中的应用(JAVA)--快速排序(Lomuto划分、Hoare划分、随机化快排)

    分治法在排序算法中的应用--快速排序 时间复杂度:平均O(nlogn),最坏O(n^2) 如果说归并排序是按照元素在数组中的位置划分的话,那么快速排序就是按照元素的值进行划分.划分方法由两种,本节将主 ...

  5. 蛮力法在查找算法中的应用(JAVA)--顺序查找

    蛮力法在查找算法中的应用 对于查找算法来说,最简单的一个思路就是逐个匹配,直到找到目标元素 顺序查找: public class Main {public static void main(Strin ...

  6. 关于二分查找算法中中间值的获取

    关于二分查找算法中中间值的获取 //left是左边元素索引的变量,right是右边元素索引的变量 int mid = (left + right) / 2; //这样写的话可能会出现问题,当数组中的元 ...

  7. 【数据结构与算法】插值查找算法、斐波那契查找算法(黄金分割法)的介绍和程序实现

    目录 1. 插值查找算法 1.1 插值查找算法的介绍 1.2 插值查找算法的程序实现 2. 斐波那契查找算法 2.1 斐波那契查找算法的介绍 2.2 斐波那契查找算法的程序实现 1. 插值查找算法 1 ...

  8. 查找算法【二叉查找树】 - 二叉查找树的查找

    查找算法[二叉查找树] - 二叉查找树的查找 因为二叉查找树的中序遍历有序性,所以查找与二分查找类似,每次都缩小查找范围,查找效率较高. [算法步骤] ① 若二叉查找树为空,查找失败,则返回空指针. ...

  9. 查找算法:斐波那契查找算法实现及分析

    斐波那契查找算法介绍 斐波那契查找法肯定与斐波那契相关嘛,斐波那契数列 又称黄金分割数列.所以我们先把黄金分割弄懂,后面代码才能看得懂!黄金分割点大家都知道吧.1:0.618或者1.618:1,我们的 ...

最新文章

  1. Redis持久化-数据丢失及解决
  2. OPA 6 - module(Create Button Test);
  3. 计算机操作系统——处理机调度算法
  4. springboot整合shiro_Springboot整合Shiro:简洁的身份认证
  5. GCD深入理解(一)
  6. python学习笔记(十二)python操作redis
  7. cvAdaptiveThreshold源代码的解析
  8. 【转】测试用例设计——WEB通用测试用例
  9. js判断是对象还是集合
  10. 计算机专业建设委员会会议记录,第一次专业建设工作会议纪要
  11. 【LDC1314】电感传感器中文手册与检测原理介绍
  12. 反馈电路反馈类型的快速判断
  13. 关于maven :pom.xml文件中父工程部分提示spring-boot-starter-parent:2.0.7.RELEAS not found
  14. 修改DNS服务器的作用,请问修改DNS服务器会有什么后果
  15. 慕名而来的博客(小白)
  16. Michael Jackson Japanese Comic
  17. 【转】2000国家大地控制网
  18. WAMP Server 安装教程
  19. ARM汇编学习(2)
  20. 小沙的长路 【欧拉图】

热门文章

  1. linux include 编译,linux-如何使用OpenSSL include编译.c文件?
  2. keil4怎么移植其他人的程序_简单和你聊聊造血干细胞移植!
  3. eclipse run on server 点不了finish_分享点经验 | springboot入门及编码
  4. java oracle sql 参数_oracle pl/sql之在java中调用带有输入输出参数的oracle存储过程...
  5. Oracle 数据怎么实时同步到 Elasticsearch | 亲测干货建议收藏
  6. matlab绘制三元位置函数,matlab – 在坐标(x,y)上用颜色z绘制(x,y,z)三元组
  7. 四叶草剧场服务器维修价格,四叶草剧场不合理报酬机制是什么-不合理报酬机制和收益详解-Appfound...
  8. java服务器要二次编译,ecology项目二次开发环境搭建
  9. Java 多个异常处理
  10. android jackson 解析json字符串,android:json解析的两个工具:Gson和Jackson的使用小样例...