`

快速排序(2个版本)

 
阅读更多

快速排序C.R.A.Hoare1962年提出的一种划分交换排序,是对冒泡排序的改进。平均情况下快速排序的时间复杂度为O(nlogn),虽然最坏情况时会达到O(n2),但在大多数情况下,快速排序要比其它O(nlogn)算法要快,被认为是目前最优秀的内部排序算法。快速排序是不稳定的。它采用分治(Divide and Conquer)的策略,把一个串行(list)分为两个子串行(sub-lists)。

步骤为:

  • 从数列中挑出一个元素,称为 "基准"pivot);
  • 分区(partition:将所有小于基准值的元素放在基准前面,所有大于基准值的元素放在基准的后面(相同的数可以到任一边)。分区结束之后,该基准就处于数列的中间位置
  • 分别对小于基准值元素的子数列和大于基准值元素的子数列进行递归排序。

递归的最底部情形,是数列的大小是零或一,在每次的迭代中,它至少会把一个元素摆到它最后的位置去。

 

1.快速排序算法一

这是在多数的教科书上所提及的版本,容易理解,选第一个元素为基准,*表示要交换的数,一趟排序的过程如下:

 

[41] 24 76* 11 45 64 21 69 19 36*  

[41] 24 36 11 45* 64 21 69 19* 76

[41] 24 36 11 19 64* 21* 69 45 76

[41] 24 36 11 19 21 64 69 45 76

21 24 36 11 19 [41] 64 69 45 76

 

代码实现:

 

public class QuickSort {
	public static void sort(int[] number) {
		sort(number, 0, number.length - 1);
	}
	
	public static void sort(int[] number, int left, int right) {
		if(left < right) {
			int s = number[left];
			int i = left;
			int j = right + 1;
			while(true) {
				while(i + 1 < number.length && number[++i] < s);//向右找
				while(j - 1 > -1 && number[--j] > s);           //向左找
				if(i >= j)
					break;
				swap(number, i, j);
			}
			number[left] = number[j];
			number[j] = s;
			sort(number, left, j -1);   //对左边进行递归
			sort(number, j + 1, right); //对右边进行递归
		}
	}
	
	public static void swap(int[] number, int i, int j) {
		int t = number[i];
		number[i] = number[j];
		number[j] = t;
		
	}
	
	public static void main(String[] args) {
		int[] number = {49,38,65,97,76,13,27,49};
		sort(number);
		for(int i = 0; i < number.length; i++) {
			System.out.print(number[i] + " ");
		}
	}
}

 

2.快速排序算法二

基准的选择是快速排序法的效率关键之一,下面介绍的快速排序算法来自算法名著 Introduction to Algorithms,算法基本思想如下:

  • 它以最右边的值s作比较的标准,将整个数列分为三个部份,一个是小于s的部份,一个是大于s的部份,一个是未处理的部份,如下所示 :

快速排序

  • 在排序的过程中,i 与 j 都会不断的往右进行比较与交换,最后数列会变为以下的状态:

 

 

快速排序

  • 然后将s的值置于中间,接下来就以相同的步骤会左右两边的数列进行排序的动作,如下所示:

 快速排序

一个实际例子的演算如下所示:

快速排序

 

代码实现:

public class QuickSort {
	public static void sort(int[] number) {
		sort(number, 0, number.length - 1);
	}
	
	public static void sort(int[] number, int left, int right) {
		if(left <= right) {
			int q = partition(number, left, right);
			sort(number, left, q - 1);
			sort(number, q + 1, right);
		}
	}
	
	public static int partition(int[] number, int left, int right) {
		int s = number[right];
		int i = left - 1;
		for(int j = left; j < right; j++) {
			if(number[j] < s) {
				i++;
				swap(number, i, j);
			}
		}
		swap(number, i + 1, right);
		return i + 1;
	}
	
	public static void swap(int[] number, int i, int j) {
		int t = number[j];
		number[j] = number[i];
		number[i] = t;
	}
	
	public static void main(String[] args) {
		int[] number = {49,38,65,97,76,13,27,49};
		sort(number);
		for(int i = 0; i < number.length; i++) {
			System.out.print(number[i] + " ");
		}
	}
}

 

0
0
分享到:
评论

相关推荐

    C经典算法之快速排序法(一)

    快速排序法(quick sort)是目前所公认最快的排序方法之一...这边所介绍的第一个快速排序法版本,是在多数的教科书上所提及的版本,因为它最容易理解,也最符合轴心分割与左右进行排序的概念,适合对初学者进行讲解。

    八大排序-java实现版

    八大排序java实现版本,直接插入排序、折半插入排序、冒泡排序、简单选择排序、希尔插入排序、快速排序 、堆排序、2-路归并排序 、基数排序,并有时间比较,博文...

    PythonQuickSort:生成一千个数字以对其进行快速排序

    生成1000个随机数,然后使用快速排序方法对其进行排序 步骤1。 设置工作环境,标题说明/自述文件。 我使用Visual Studio Code和Python作为该项目的工作环境。 然后,我在github帐户中创建了一个README文件,以显示...

    File_Processing:通过改进的快速排序进行外部排序

    文件_处理通过改进的快速排序进行外部排序您将为二进制数据实现外部排序算法。 输入数据文件将由许多 4 字节记录组成,每个记录由 1 到 30,000 范围内的两个 2 字节(短)整数值组成。 第一个 2 字节字段是键值...

    迭代版的快速排序,不是递归的,速度并不会快多少-易语言

    写完了 迭代版快速排序,用1个参数一样大小的游标数组(记录左右的起始点终点),储存了原来的栈 13|56 78|10,11 例如第一组,被4分割成两个,左右是1 3, 第二个是 5 ,6 然后用第一组数组,计算得出第二组游标...

    10个数据结构课程 设计实例 二叉树建立遍历 冒泡排序 快速排序等

    1.C语言版本的数据结构实例 2.适合人群:学生、自学爱好者、职场人 3.应用场景:作业、实操、考试

    精心整理史上最全的数据结构flash演示动画,共5个版本,祝大家考研成功!

    \数据结构flash演示\版本2\10.5 归并排序2.swf \数据结构flash演示\版本2\2.1 线性表的类型定义.swf \数据结构flash演示\版本2\2.3 线性表的链式表示和实现-单链表到循环链表的转化.swf \数据结构flash演示\版本2...

    数据结构演示器

    其中包括插入排序、冒泡排序、选择排序和2个快速排序(快速排序2 为改进版本)。同时该演示器实时显示当前算法中比较操作和移动操作(交换视为2次移动)的次数,以供用户比较各排序算法的效率。另外该演示器还提供...

    归并排序优化完比某些快速排序还要快-易语言

    归并排序优化完比某些快速排序还要快。 原来用了自定义shuj类型很慢,经过好几个版本的优化,现在(无重复shuj下)已经比平常的归并排序快了。 还是没有系统自带的支持库快排与汇编快排更快就是 一千万shuj下 ,10秒...

    宝元数控+MW2200+家具木门免拉手+无尘加工+补板功能+最新排序加工+快速打孔

    宝元系统 MW2200和MW2500专用升级包其他版本不要用 新老系统升级以后可直接增加一下功能 无需额外费用 即刻拥有最新功能 1 排序加工 2 各种免拉手工艺 参数化加工 3无尘加工 四个方向吹气 4补板功能 5 快速打孔 ...

    改进的快速排序查找多目标优化算法附matlab源码.zip

    1.版本:matlab2014/2019a,内含运行结果,不会运行可私信 2.领域:智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机等多种领域的Matlab仿真,更多内容可点击博主头像 3.内容:标题...

    改进的快速排序查找多目标优化算法附matlab源码.zip.zip

    1.版本:matlab2014/2019a,内含运行结果,不会运行可私信 2.领域:智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机等多种领域的Matlab仿真,更多内容可点击博主头像 3.内容:标题...

    快速排序的四种python实现(推荐)

    快速排序算法,简称快排,是最实用的排序算法,没有之一,各大语言标准库的排序函数也基本都是基于快排实现的。 本文用python语言介绍四种不同的快排实现。 1. 一行代码实现的简洁版本 quick_sort = lambda array: ...

    学生信息管理系统C语言版本

    设计并实现一个学生管理系统,即定义一个包含学生信息(学号,姓名,成绩)的顺序表,可以不考虑...7. 利用快速排序按照学号进行排序; 8. 根据姓名进行折半查找,要求使用递归算法实现,成功返回此学生的学号和成绩;

    选择排序——Java实现

    冒泡排序实际上是将数据从右至左排序完成(从右至左、从大到小进行交换排序),而快速排序是将数据从左到右排序完成(从左至右、从小到大进行交换排序),虽然选择排序相对于冒泡排序将交换次数从O(n2)O(n^2)O(n2)...

    lampsort:LampSort,一种非递归快速排序

    它选择一个主元,它可以是区间内的任何元素,甚至只是我们在这里所做的第一个元素,然后将区间分成 2 个子区间:一个元素小于枢轴,一个元素大于枢轴,移动元素。 枢轴自动留在正确的位置。 QuickSort 循环,从整个...

    十五个经典算法研究与总结、目录+索引(定稿版)

    前言: 本人的原创作品经典算法研究系列,...十二(再续):快速排序算法之所有版本的c/c++实现 十三、通过浙大上机复试试题学SPFA 算法 十四、快速选择SELECT算法的深入分析与实现 十五、多项式乘法与快速傅里叶变换

    sorting-algorithms:摆脱(排序)算法的困扰

    排序算法 摆脱(排序)算法的困扰。... 例如,快速排序的实现包括许多版本,具体取决于如何选择枢轴元素,它是序列的第一个,第二个,中间,最后一个还是随机元素。 测验 您可以通过将整数序列传递给相应的脚本来测

Global site tag (gtag.js) - Google Analytics