快速排序(18JavaB5,9’)

以下代码可以从数组a[]中找出第k小的元素。

它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的。

请仔细阅读分析源码,填写划线部分缺失的内容。

import java.util.Random;
public class Main{
public static int quickSelect(int a[], int l, int r, int k) {
Random rand = new Random();
int p = rand.nextInt(r - l + 1) + l;
int x = a[p];
int tmp = a[p]; a[p] = a[r]; a[r] = tmp;
int i = l, j = r;
while(i < j) {
while(i < j && a[i] < x) i++;
if(i < j) {
a[j] = a[i];
j--;
}
while(i < j && a[j] > x) j--;
if(i < j) {
a[i] = a[j];
i++;
}
}
a[i] = x;
p = i;
if(i - l + 1 == k) return a[i];
if(i - l + 1 < k) return quickSelect( _________________________________ ); //填空
else return quickSelect(a, l, i - 1, k);
}
public static void main(String args[]) {
int [] a = {1, 4, 2, 8, 5, 7};
System.out.println(quickSelect(a, 0, 5, 4));
}
}

注意:只提交划线部分缺少的代码,不要抄写任何已经存在的代码或符号。


先看看典型的快速排序

快速排序

快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序

它采用了一种分治(Divide-and-ConquerMethod)的策略

基本思想

1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

先把基准值(最左)存起来

高位(右)大的往左边拉

低位(左)小的往右边拉

最后,存的那个基准值(曾经最左)放中间

对左:相同处理

对右:相同处理

package bb;
public class QuickSortMy {
static void printArray(int a[]) {
for (int i : a) {
System.out.print(i + "\t");
}
System.out.println();
}
static void qsort(int a[], int left, int right) {
if (left >= right) {
return;
}
printArray(a);
int key = a[left];
int i = left, j = right;
while (i < j) {
while (i < j && a[j] > key) {
j--;
}
if (i < j) {
System.out.printf("a[%d]=%d <- a[%d]=%d\n", i, a[i], j, a[j]);
a[i++] = a[j];
}
while (i < j && a[i] < key) {
i++;
}
if (i < j) {
System.out.printf("a[%d]=%d -> a[%d]=%d\n", i, a[i], j, a[j]);
a[j--] = a[i];
}
}
a[i] = key;
printArray(a);
qsort(a, left, i - 1);
qsort(a, i + 1, right);
}
public static void main(String[] args) {
int a[] = { 3, 4, 5, 1, 2 };
qsort(a, 0, a.length - 1);
}
}

2018JavaB组第5题的参考答案+注释如下所示:

package bb;
import java.util.Random;
public class JB18_5快速排序 {
public static int quickSelect(int a[], int l, int r, int k) {
Random rand = new Random();
int p = rand.nextInt(r - l + 1) + l;
int x = a[p];
int tmp = a[p];
a[p] = a[r];
a[r] = tmp;
int i = l, j = r;
while (i < j) {
while (i < j && a[i] < x)
i++;
if (i < j) {
a[j] = a[i];
j--;
}
while (i < j && a[j] > x)
j--;
if (i < j) {
a[i] = a[j];
i++;
}
}
a[i] = x;
p = i;
if (i - l + 1 == k)// (1)说明到底了
return a[i];
if (i - l + 1 < k)
return quickSelect(a, i + 1, r, k - i + l - 1); // 填空
// qsort(a, i + 1, right);
// (3)先试试k,
// (4)再考虑:k要移动到等于(i - l + 1),试试k-(i - l + 1)
else
// i - l + 1 > k
return quickSelect(a, l, i - 1, k);// (2)qsort(a, left, i -
// 1);对上了,k不变
}
public static void main(String args[]) {
int[] a = { 1, 4, 2, 8, 5, 7 };
System.out.println(quickSelect(a, 0, 5, 4));
// int [] a = {1, 4, 2, 8, 5, 7, 23, 58, 16, 27, 55, 13, 26, 24, 12, 2};
// System.out.println(quickSelect(a, 0, a.length-1, 6));
}
}

蓝桥杯——快速排序(2018JavaB组第5题9分)的更多相关文章

  1. 第八届蓝桥杯java b组第六题

    标题:最大公共子串 最大公共子串长度问题就是:求两个串的所有子串中能够匹配上的最大长度是多少. 比如:"abcdkkk" 和 "baabcdadabc",可以找 ...

  2. 蓝桥杯——螺旋折线(2018JavaB组第7题19分)

    螺旋折线(18JB-7-19') 如图p1.pgn所示的螺旋折线经过平面上所有整点恰好一次. 对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度. ...

  3. 2018年蓝桥杯java b组第五题

    标题:快速排序 以下代码可以从数组a[]中找出第k小的元素. 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的. 请仔细阅读分析源码,填写划线部分缺失的内容. 我在使用(a, l, r, ...

  4. 第六届蓝桥杯java b组第五题

    九数组分数 1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法? 下面的程序实现了该功能,请填写划线部分缺失的代码. public class A { public static vo ...

  5. 第六届蓝桥杯java b组第四题

    第四题 两个整数做除法,有时会产生循环小数,其循环部分称为:循环节. 比如,11/13=6=>0.846153846153….. 其循环节为[846153] 共有6位. 下面的方法,可以求出循环 ...

  6. 第六届蓝桥杯java b组第三题

    第三题 三羊献瑞 观察下面的加法算式: 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字. 请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容. 答案这个题目完全可以使用暴 ...

  7. 第八届蓝桥杯java b组第三题

    标题:承压计算 X星球的高科技实验室中整齐地堆放着某批珍贵金属原料. 每块金属原料的外形.尺寸完全一致,但重量不同.金属材料被严格地堆放成金字塔形. 7                         ...

  8. 第三届蓝桥杯Java高职组决赛第一题

    题目描述: 看这个算式: ☆☆☆ + ☆☆☆ = ☆☆☆ 如果每个五角星代表 1 ~ 9 的不同的数字. 这个算式有多少种可能的正确填写方法? 173 + 286 = 459 295 + 173 = ...

  9. 2018年蓝桥杯java b组第八题

    标题:日志统计 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有N行.其中每一行的格式是: ts id 表示在ts时刻编号id的帖子收到一个"赞" ...

随机推荐

  1. D. Equalize the Remainders 解析(思維)

    Codeforce 999 D. Equalize the Remainders 解析(思維) 今天我們來看看CF999D 題目連結 題目 略,請直接看原題 前言 感覺要搞個類似\(stack\)的東 ...

  2. c语言创建dll以及使用

    0x01. declspec(dllexport)创建导出dll 笔者这边使用vs 2015,但是性质都一样的 新建项目 -> Win32控制台应用程序 -> dll 这时候就创建了一个项 ...

  3. 4G DTU模块和串口设备连接的方式

    首先说下解决思路: 由于考虑到串口开发很麻烦,所以后来买了一个4g模块的dtu. 所以最后的解决方案是,plc串口设备与dtu相连,由于dtu是透传模式,使用java与4g模块进行通信就完事了. 虽然 ...

  4. Viper 微服务框架 编写一个hello world 插件-02

    1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...

  5. JavaWeb项目问题记录

    模板 [遇到的问题] [时间] [原因] [解决方案] [排查思路及方式] 思路: 1) 2) [遇到的问题] 品优购项目中运营商页面查询广告信息是,无法正常查询,错误如下: Failed to lo ...

  6. sync_with_stdio(false)的副作用

    sync_with_stdio()的一个特性 水一篇随笔 其实对于用快读的大佬来说没什么用,但还是提一下 ios::sync_with_stdio(false)用处是"关闭同步", ...

  7. 转载:解密Redis持久化

    本文内容来源于Redis作者博文,Redis作者说,他看到的所有针对Redis的讨论中,对Redis持久化的误解是最大的,于是他写了一篇长文来对Redis的持久化进行了系统性的论述.文章非常长,也很值 ...

  8. setTimeout、同步、异步的理解

    console.log('111'); setTimeout(()=>{ console.log('222') },1000); console.log('333'); setTimeout(( ...

  9. ZOJ 1091 Knight Moves(BFS)

    Knight Moves A friend of you is doing research on the Traveling Knight Problem (TKP) where you are t ...

  10. Centos8防火墙设置

    1.centos中firewalld与iptables centos7以前的版本默认使用iptables服务进行管理防火墙规则.centos7以及其以上版本默认使用firewalld服务管理防火墙.所 ...