快速排序以及第k小元素的线性选择算法
简要介绍下快速排序的思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。时间复杂度为O(nlogn)
一.《data structure and algorithm analysis in c》中的实现,测试过,觉得该说明的已经注释
|
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#include<stdio.h>
#define LEN 15 #define CUTOFF 3 //用c++则可以写成引用 void swap(int *const p1, int *const p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; } //插入排序 void insertion_sort(int a[], int n) { int i, j; int tmp; for (i = 1; i < n; i++) { tmp = a[i]; for (j = i; j > 0 && a[j - 1] > tmp; j--) a[j] = a[j - 1]; a[j] = tmp; } } // return median of left, center, and right void qsort(int a[], int left, int right) int main(void) |
二.不对pivot进行中位数取值的简易版本
|
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 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include<stdio.h>
#define LEN 15 void swap(int *const p1, int *const p2) void qsort(int a[], int left, int right) int main(void) |
三.根据简易快速排序得出的第k小选择算法
|
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 34 35 36 37 38 39 40 41 42 43 44 45 |
#include<stdio.h>
#define LEN 15 #define K 6 void swap(int *const p1, int *const p2) int qsort(int k, int a[], int left, int right) int main(void) |
四.中位数之第k小的线性选择算法
实现该算法的步骤如下:
1.如果n是一个比较小的数,比如n<6,那么只需要对此无序数组进行排序后,即可很容易的得到第K小元素。
此时约束时间T=7。
2.如果n>5,那么我们将这个无序数组分成五组。此时约束时间T=n/5。
3.找出每组的中位数,构成集合M。此时的约束时间T=7n/5.
4.递归的调用selection(M,|M|/2)算法查找上一步中所有中位数的中位数,设为m。此时的约束时间
T=T(n/5)。
5.用m来分割此时的数组,比较m与其他的(n-1)个数,小于m的数置于左集合L,大于m的数置于右集合R。当
然,中位数m的下标r=|L|+1(|L|是左集合L的个数)。此时的约束时间T=T(n)。
如果r=k,那么返回m。
如果r<k,那么在小于m的左集合L中递归查找第K小数。
如果r>k,那么在大于m的右集合R中递归查找第K小数。
动态图示参见:http://ds.fzu.edu.cn/fine/resources/FlashContent.asp?id=82
-----------------------------------------------------------------------------------------------------------------------------------------
参考:http://bbs.chinaunix.net/thread-116218-1-1.html
http://blog.csdn.net/fengchaokobe/article/details/6784721
http://ds.fzu.edu.cn/fine/resources/FlashContent.asp?id=82
中位数之第K小的线性选择算法
1973年,Blum、Floyd等几位大仙合并一体,写了一篇题为 “Time bounds for selection” 的章,给出了一种在数组中选出第k小元素的算法,俗称"中位数之中位数算法"。该算法从理论上保证了最坏情形下的线性时间复杂度(O(n))。而一个简单的排序算法像快速排序的时间复杂度是O(nlogn),利用类似于快速排序的做法是:首先对该无序数组进行排序(O(nlogn)),然后进行一次遍历(O(k))就可以找到第k小元素。下面我们来重点看看中位数排序法。
该算法使用分而治之的策略,查找到第K小元素在最坏情况下的时间复杂度为O(n)。
实现该算法的步骤如下:
1.如果n是一个比较小的数,比如n<6,那么只需要对此无序数组进行排序后,即可很容易的得到第K小元素。
此时约束时间T=7。
2.如果n>5,那么我们将这个无序数组分成五组。此时约束时间T=n/5。
3.找出每组的中位数,构成集合M。此时的约束时间T=7n/5.
4.递归的调用selection(M,|M|/2)算法查找上一步中所有中位数的中位数,设为m。此时的约束时间
T=T(n/5)。
5.用m来分割此时的数组,比较m与其他的(n-1)个数,小于m的数置于左集合L,大于m的数置于右集合R。当
然,中位数m的下标r=|L|+1(|L|是左集合L的个数)。此时的约束时间T=T(n)。
如果r=k,那么返回m。
如果r<k,那么在小于m的左集合L中递归查找第K小数。
如果r>k,那么在大于m的右集合R中递归查找第K小数。
递归方程:T(n)=O(n) + T(n/5) + T(7n/10) (证明过程略)
如果你想知道怎样得到次方程的,不妨找一本关于算法的书看一看或直接给我留言,谢谢!
另外,我想说的是:我为什么分为五组而不是分为其他的组。
假设我们将此数组分为三组,那么有:T(n) = O(n) + T(n/3) + T(2n/3) so T(n) > O(n)。如果我
们将此数组分成五组以上,那么就会显得有些麻烦了,所以分为五个组是最理性的选择。
由于鄙人的翻译水平所致,文中不妥之处还望各位指出来,谢谢!
快速排序以及第k小元素的线性选择算法的更多相关文章
- 快速排序-无序数组K小元素
13:07:382020-03-10 11:16:13 问题描述: 找到一个无序数组中第K小的数 样例 1: 输入: [3, 4, 1, 2, 5], k = 3 输出: 3 样例 2: 输入: [1 ...
- 清橙OJ 1082 查找第K小元素 -- 快速排序
题目地址:http://oj.tsinsen.com/A1082 问题描述 给定一个大小为n的数组s和一个整数K,请找出数组中的第K小元素. 这是一个补充程序的试题,你需要完成一个函数: int fi ...
- 算法导论学习之线性时间求第k小元素+堆思想求前k大元素
对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...
- 寻找第K小元素
要在一个序列里找出第K小元素,可以用排序算法,然后再找.可以证明,排序算法的上界为O(nlogn). 在这里,给出两种可以在线性时间内找出第K小元素的方法. 方法1: (1) 选定一个比较小的阈值(如 ...
- 中位数与第K小元素
算法实际上是模仿快速排序算法设计出来的,其基本思想也是对输入数组进行递归划分,与快速排序不同的是,它只对划分出来的子数组之一进行递归处理: int randompartition(int a[],in ...
- Ex 2_22 两个有序列表合并后的第k小元素..._第四次作业
package org.xiu68.ch02; public class Ex2_22 { public static void main(String[] args) { // TODO Auto- ...
- 有序矩阵中第k小元素
有序矩阵中第k小元素 题目: 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 看到有序就会想 ...
- 查询无序列表中第K小元素
当需要在无需列表中寻找第k小的元素时,一个显然的方法是将所有数据进行排序,然后检索k个元素.这种方法的运行时间为O(n log(n)). 无序列表调用分区函数将自身分解成两个子表,其长度为i和n-i. ...
- 找出数组[1...n]中第k小元素
//问题描述: 试编写一个算法,使之能够在数组L[1...n]中找出第k小的元素(即从小到大排序后处于第k个位置的元素) #include <stdio.h> // 结合快排思想,查找第5 ...
随机推荐
- mount 和 umount 命令
参考:http://man.chinaunix.net/linux/mandrake/101/zh_cn/Command-Line.html/fs-and-mntpoints-mount.html 现 ...
- Confman - 针对「Node 应用」的配置文件加载模块
一句话介绍 confman 是一个强大的配置文件加载器,无论你喜欢 yaml .cson.json.properties.plist.ini.toml.xml 还是 js,都能满足你的愿望,并且更加简 ...
- 运行Hadoop的示例程序WordCount-Running Hadoop Example
In the last post we've installed Hadoop 2.2.0 on Ubuntu. Now we'll see how to launch an example ma ...
- 用指令来构建IIS7
工作上要部署iis7+net4.0环境,发现30多台机子都没有用装有IIS7镜像来安装,都必须自己手动. 作为程序猿,真要一台台装的话,就真对不起自己的职业.于是想到用bat来执行任务,找到了安装II ...
- DEDECMS网站管理系统Get Shell漏洞
漏洞版本: DEDECMS 5.3/5.6 漏洞描述: DedeCms 基于PHP+MySQL的技术开发,支持Windows.Linux.Unix等多种服务器平台,从2004年开始发布第一个版本开始, ...
- kubernetes基础概念
kubernetes是基于容器技术的分布式架构领先方案.具有完备的集群管理能力,包括多层次的安全防护和准入机制.多租户应用支撑能力.透明的服务注册和服务发现机制.内建智能负载均衡器.强大的故障发现和自 ...
- MatLab2012b/MatLab2013b 分类器大全(svm,knn,随机森林等)
train_data是训练特征数据, train_label是分类标签.Predict_label是预测的标签.MatLab训练数据, 得到语义标签向量 Scores(概率输出). 1.逻辑回归(多项 ...
- 免费资源:Bootstrap开发的创意模板
在线演示 免费下载 一套免费的Bootstrap网站模板,使用现代的布局并支持响应式.拥有非常棒的CSS3动画效果及其滚动效果.
- Java学习笔记七(目录操作)
1.介绍 上一篇博客介绍的是java中经常使用的操作文件的方式,本篇博客着重解说一下,在Java中是怎样来操作目录的.主要是利用的是Java.IO包以下的File类,本篇博客着重解说一下该类的构造函数 ...
- Mysqldump参数大全(参数来源于mysql5.5.19源码)
参数 参数说明 --all-databases , -A 导出全部数据库. mysqldump -uroot -p --all-databases --all-tablespaces , -Y ...