快速排序以及第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 ...
随机推荐
- 用C++/CLI搭建C++和C#之间的桥梁(四)—— 网络资源
关于C++/CLI的基础,我前面已经写过了几篇文章介绍过一些了,不过这些基本上都是管中窥豹,如果要详细了解C++/CLI,MSDN无疑是最好的教程. 使用 C++ 互操作(隐式 PInvoke) Vi ...
- TF卡翻盖式卡座
- DELPHI PROTOBUF免费的开源支持库fundamentals5
DELPHI PROTOBUF免费的开源支持库fundamentals5 1.源码URL: https://github.com/fundamentalslib/fundamentals5 2.编译P ...
- 【mysql】二级索引----聚簇索引和非聚簇索引-----
参考地址: https://blog.csdn.net/bigtree_3721/article/details/51335479 https://blog.csdn.net/roxliu/artic ...
- Java:泛型在编译时会被檫除,Eclipse 如何给出智能提示?
背景 Java 的泛型是一种语法糖,编译时会被“檫除”,参考文章:http://docs.oracle.com/javase/tutorial/java/generics/,如果没有源代码,Eclip ...
- 为Hadoop创建JAR包文件Creating a JAR for Hadoop
We've seen the internals of MapReduce in the last post. Now we can make a little change to the WordC ...
- c#抓去网页
c#利用WebClient和WebRequest获取网页源代码的比较 2011-11-28 10:26:42 我来说两句 收藏 我要投稿 C#中一般是可以利用WebClient类和WebReq ...
- Thinkphp学习笔记-编辑工具Sublime license
选择[help]-[enter license] 直接输入注册码就可以了 ----- BEGIN LICENSE ----- Andrew Weber Single User License EA ...
- (LeetCode 49)Anagrams
Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be ...
- 从零开始编写自己的C#框架(25)——网站部署 【转】
服务器安全部署文档 目录1. 前言.. 3 2. 部署环境.. 3 2.1 服务器环境信息.. 3 3. 磁盘阵列配置.. 4 4. 安装操作系统.. ...