选取第K大数的快速选择算法和注意事项
快速选择算法,是一种能在大致O(N)的时间内选取数组中第k大或者k小的算法.其基本思路与快速排序算法类似,也是分治的思想.
其实这个算法是个基础算法,但是不常用,所以今天编的时候错了POJ2388,才有了这篇文章.
- 执行Partition算法(就是那个快排里将区间内所有数划分为小的一部分和大的一部分的过程)
- 判断第k大的数是在小的部分还是大的部分
- 递归,直到区间足够小,返回结果
下面几段代码,尤其要注意的是
while(i<j)
还是
while(i<=j)
程序1:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*
Program:快速选择算法样例
Author:Comzyh
*/
#include <cstdio>
int array[10000],temp;
int N,K;
int QuickSelect(int arr[],int b,int e,int k);
int main()
{
scanf("%d%d",N,K);
for (int i=1;i<=N;i++)
scanf("%d",array[i]);
printf("The k th :%d\n",QuickSelect(array,1,N,K));
}
int QuickSelect(int arr[],int b,int e,int k)
{
int i=b,j=e,mid=arr[(i+j)>>1];
while (i<=j)//注意,小于等于
{
while (arr[i]<mid)i++;
while (arr[j]>mid)j--;
if (i<=j)
{
temp=arr[i];arr[i]=arr[j];arr[j]=temp;
i++;j--;
}
}
if (b<j k<=j)return QuickSelect(arr,b,j,k);//分治
if (i<e k>=i)return QuickSelect(arr,i,e,k);
return arr[k];//如果不属于任何一方,就结束,返回
}
|
不过,就是这样一个简单的算法,今天也出了点错误,本来我是用用了多少年的快排改的,就像下面这段代码
程序2:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/*
Program:快速排序算法样例
Author:Comzyh
*/
#include <cstdio>
int array[10000],temp;
int N,K;
int QuickSort(int arr[],int b,int e);
int main()
{
scanf("%d",N);
for (int i=1;i<=N;i++)
scanf("%d",array[i]);
QuickSort(array,1,N);
for (int i=1;i<=N;i++)
printf("%d\n",array[i]);
}
int QuickSort(int arr[],int b,int e)
{
int i=b,j=e,mid=arr[(i+j)>>1];
while (i<j)//注意,小于
{
while (arr[i]<mid)i++;
while (arr[j]>mid)j--;
if (i<=j)
{
temp=arr[i];arr[i]=arr[j];arr[j]=temp;
i++;j--;
}
}
if (b<j)QuickSort(arr,b,j);
if (i<e)QuickSort(arr,i,e);
}
|
几乎一模一样,但是下面这样写就是是错的
程序3:
|
1
2
3
4
5
6
7
8
9
10
11
|
int QuickSelect(int arr[],int b,int e,int k)
{
int i=b,j=e,mid=arr[(i+j)>>1];
while (i<j)//注意,小于
{
....
}
if (b<j k<=j)return QuickSelect(arr,b,j,k);//分治
if (i<e k>=i)return QuickSelect(arr,i,e,k);
return arr[k];//如果不属于任何一方,就结束,返回
}
|
而这样写是对的
程序4:
|
1
2
3
4
5
6
7
8
9
10
11
|
int QuickSelect(int arr[],int b,int e,int k)
{
int i=b,j=e,mid=arr[(i+j)>>1];
while (i<j)//注意,小于
{
....
}
if (b<j k<=j)QuickSelect(arr,b,j,k);//没有Return
if (i<e k>=i) QuickSelect(arr,i,e,k);
return arr[k];//如果不属于任何一方,就结束,返回
}
|
快速选择算法细节演示- 按照错误的方法(程序3)执行(如图(3)),函数会在闭区间[1,4]中寻找答案,这样是错误的,因为arr[5]=3不在这个区间内
- 按照程序1中的方法执行,j会自减1,因为不满足i<=j(i=4,j=3)然后会在闭区间[4,6]中递归(如图(4)),寻找答案,这样是正确的
- 按照程序4中的方法执行,QuickSelect(1,4,4)执行完之后arr[4]=6,这样,再执行QuickSelect(4,6,4)时,程序会返回正确的结果
选取第K大数的快速选择算法和注意事项的更多相关文章
- 蓝桥杯 算法训练 区间k大数查询(水题)
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
- 算法训练 区间k大数查询
http://lx.lanqiao.org/problem.page?gpid=T11 算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个 ...
- POJ 2388 Who's in the Middle (快速选择算法:O(N)求数列第K大)
[题意]求数列中间项. ---这里可以扩展到数列第K项. 第一次做的时候直接排序水过了= =--这一次回头来学O(N)的快速选择算法. 快速选择算法基于快速排序的过程,每个阶段我们选择一个数为基准,并 ...
- 蓝桥杯--算法训练 区间k大数查询
算法训练 区间k大数查询 时间限制:1.0 ...
- 普林斯顿大学算法课 Algorithm Part I Week 3 求第K大数 Selection
问题 给定N个元素的数组,求第k大的数. 特例当k=0时,就是求最大值,当k=N-1时,就是求最小值. 应用顺序统计求top N排行榜 基本思想 使用快速排序方法中的分区思想,使得a[k]左侧没有更小 ...
- 算法训练 区间K大数
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
- 分治算法--寻找第k大数
问题描述:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k大的元素,(这里给定的线性集是无序的). 其实这个问题很简单,直接对线性序列集qsort,再找出第k个即可.但是这样的 ...
- 蓝桥杯算法训练 区间k大数查询
算法训练 区间k大数查询 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二行包含n个正整数,表示给定的序列. 第三个 ...
- Java实现 蓝桥杯 算法训练 区间k大数
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二 ...
随机推荐
- Freemarker入门小案例(生成静态网页的其中一种方式)
其实生成静态网页的方式有好多种,我昨天看了一下,Freemarker是其中一种,但是Freemarker现在我们都用得比较少了,现在用得ActiveMQ用来发送信息到静态页面,不过想了一下这个小东西, ...
- vuejs 中 select 动态填充数据,后台的数据
selected:"A" 对 selected:A 错. 变量不用引号. 内容一定要引号. https://jsfiddle.net/rgnuaw30/ ...
- java第九次作业:第九章例题3个
作业1: 例题9.1 制作圆类,根据圆的半径求出周长及面积 package com.swift; //抽象的方法构成类,把属性和方法进行封装 public class Circle { // 两个方面 ...
- 使用Spring AOP实现业务依赖解耦
Spring IOC用于解决对象依赖之间的解耦,而Spring AOP则用于解决业务依赖之间的解耦: 统一在一个地方定义[通用功能],通过声明的方式定义这些通用的功能以何种[方式][织入]到某些[特定 ...
- [POJ] 2411 Mondriaan's Dream
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18903 Accepted: 10779 D ...
- django-ckeditor添加代码功能(codesnippet)
最近做了一个博客,使用python3+django2.1开发的,后台编辑器和前端显示用的Django-ckeditor富文本编辑器,由于发现没有代码块功能,写上去的代码在前端展示有点乱,于是一顿问度娘 ...
- GIMP语言设置
初学GIMP,需要设置语言:点击 编辑 - 首选项 其他的配置如: 配置快捷键 自己熟悉吧!
- python数据类型、字符编码、文件处理-练习
练习-字符串 # 写代码,有如下变量,请按照要求实现每个功能 (共6分,每小题各0.5分) name = " aleX" # ) 移除 name 变量对应的值两边的空格,并输出处理 ...
- HTML 文件类表单元素如何限制上传类型,Accept属性设置
需求描述:简单的控制file的选择类型 解决方法:使用HTML input file 的accept属性控制 实例: <form action="demo_form.asp" ...
- fork()函数,一次调用,两次返回
参考自:http://blog.csdn.net/dog_in_yellow/archive/2008/01/13/2041079.aspx 以前一直迷惑,什么叫一次调用,两次返回.通过上网搜索,终于 ...