快速排序(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. git 常用命令大全2

    查看.添加.提交.删除.找回,重置修改文件 git help <command> # 显示command的help git show # 显示某次提交的内容 git show $id gi ...

  2. 对精致码农大佬的 [理解 volatile 关键字] 文章结论的思考和寻找真相

    一:背景 1. 讲故事 昨天在园里的编辑头条看到 精致码农大佬 写的一篇题为:[C#.NET 拾遗补漏]10:理解 volatile 关键字 (https://www.cnblogs.com/will ...

  3. 【Postman】使用Postman实现接口数据关联

    首先下载安装Postman直接打开官网,点击下载按钮即可完成下载https://www.getpostman.com/downloads/ 栗子业务场景:用户登录医生账户,查询自己的处方列表数据:用户 ...

  4. SpringCloud gateway 过滤

    如果需要获取一张图片但服务器没有过滤图片请求地址时,每次请求图片都需要携带token等安全验证密钥,可到nacos配置网关(gateway)的security配置,可过滤掉你配置的url(可理解为白名 ...

  5. Spring 自调用事务失效,你是怎么解决的?

    前言 相信大家都遇到一种事务失效场景,那就是 Spring 自调用,就是在 Service 方法内,调用另一个加 @Transactional 注解的方法,发现事务失效,这时候你是怎么解决的呢? 公众 ...

  6. 【Kata Daily 190911】Multiplication Tables(乘法表)

    题目: Create a function that accepts dimensions, of Rows x Columns, as parameters in order to create a ...

  7. leetcode73:minmum-window-substring

    题目描述 给出两个字符串S和T,要求在O(n)的时间复杂度内在S中找出最短的包含T中所有字符的子串. 例如: S ="ADOBECODEBANC" T ="ABC&quo ...

  8. [.Net Core 3.0+/.Net 5] System.Text.Json中时间格式化

    简介 .Net Core 3.0开始全新推出了一个名为System.Text.Json的Json解析库,用于序列化和反序列化Json,此库的设计是为了取代Json.Net(Newtonsoft.Jso ...

  9. 内网渗透 day5-msf本地提权(windows)

    msf本地提权 目录 1. 利用uac提权 1 2. 绕过uac认证 2 3. 利用windows本地提权漏洞进行提权 4 1. 利用uac提权 前提与目标机建立会话连接 seach local/as ...

  10. git操作之二:git restore

    在上篇博客中留了一个问题,那就是git restore命令是做什么的,下面重点分析. 一.概述 git restore命令是撤销的意思,也就是把文件从缓存区撤销,回到未被追踪的状态. 该命令有git ...