算法---快速排序(quick sort)

在前面介绍的排序算法中,最快的排序算法为归并排序,但是归并排序有一个缺陷就是排序过程中需要O(N)的额外空间。本文介绍的快速排序算法时一种原地排序算法,所需的额外空间复杂度为O(1)。

算法介绍:快速排序其实一种根据需找某个元素的具体位置进行排序的方法。比如所存在如下数组

选择第一个元素5,找到5最终的位置,即5的左边的数都小于或者等于5,右边的数都大于或者等于5.

从"6"开始,可知6大于5,此处停住,从“2”开始2小于5,因此交换6与2的位置,然后接着往下走,将所有小于等于5的都放在左边,大于等于5的都放在右边,等到如下所示的数组:

此时的索引在4的位置,然后交换5和4的位置,这样就保证了左边的都小于5,右边的都大于5。

然后再分别对5的左右两边重复上述过程即可将数组按升序排列。

算法发复杂度分析:假设每次都从中间将数组分开,且算法的运行时间为T(N),则依据算法的执行过程可知,找到当前元素的位置需要扫面一遍数组即N次,然后再对此元素两边的子数组重复上述操作。为此T(N)=2*T(N/2)+N,解得T(N)=O(NlogN)。

算法实现:

寻找切分点

int sort::partition(int* a, const int low, const int high)
{
	int value = a[low];
	int i=low;
	int j=high+1;
	while (1)
	{
		while(a[++i] < value)
		{
			if(i == high) break;
		}
		while(value < a[--j]);
			//a[low] == value,因此可以知道j==low时,此判断条件不成立,可知此时i必大于j,从而整个循环结束。
		if(i>=j)
			break;
		swap(a,i,j);
	}
	swap(a,low,j);
	return j;
}

快速排序:

void sort::quick_sort(int* a, const int low, const int high)
{
	if(low >= high)
		return;
	int loc = partition(a,low,high);
	quick_sort(a,low,loc-1);
	quick_sort(a,loc+1,high);
}

上述即为快速排序的具体实现。但是对上述算法还有很多的改进之处,比如说对存在大多数重复数据的数组排序,初始切分点的选取等等都可以进行改进。具体的改进如下所示:

对于较小的子数组使用插入排序:

void sort::insert_sort_update(int* a, const int n)
{
	for(int i=1; i<n; i++)
	{
		int j=i;
		int temp = a[i];
		for(; j>0 && temp < a[j-1]; j--)
		{
			a[j] = a[j-1];
		}
		a[j] = temp;
	}
}
void sort::quick_sort_update_with_insert_sort(int* a, const int low, const int high)
{
	if(high <= low+N)
	{
		insert_sort_for_update(a,low,high);
		return;
	}
	int loc = partition(a,low,high);
	quick_sort_update_with_insert_sort(a,low,loc-1);
	quick_sort_update_with_insert_sort(a,loc+1,high);
}

对于含有大多数重复元素的改进:

void sort::quick_sort_update_with_partition(int* a,const int low, const int high)
{
	if(low>=high)
		return;
	int lt = low;
	int gt = high;
	int value = a[low];
	int i=low+1;
	while(i<=gt)
	{
		if(a[i]<value)
		{
			swap(a,i,lt);
			i++;
			lt++;
		}
		else if(a[i] > value)
		{
			swap(a,i,gt);
			gt--;
		}
		else
		{
			i++;
		}
	}
	quick_sort_update_with_partition(a,low,lt-1);
	quick_sort_update_with_partition(a,gt+1,high);
}

上述博文主要介绍了快速排序算法及其改进。欢迎拍砖

时间: 2024-10-23 19:45:27

算法---快速排序(quick sort)的相关文章

经典排序算法 - 快速排序Quick sort

经典排序算法 - 快速排序Quick sort 原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 举个例子 如无序数组[6 2 4 1 5 9] a),先把第一项[6]取出来, 用[6]依次与其余项进行比较, 如果比[6]小就放[6]前边,2 4 1 5都比[6]小,所以全部放到[6]前边 如果比[6]大就放[6]后边,9比[6]大,放到[6

排序算法 - 快速排序(Quick Sort)

算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). (1) 分治法的基本思想    分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题.递归地解这些子问题,然后将这些子问题的解组合为原问题的解. (2)快速排序的基本思想    设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为:分解:      在R[low..hi

排序算法之快速排序(Quick Sort) -- 适用于Leetcode 75 Sort Colors

Quick Sort使用了Divide and Concur的思想: 找一个基准数, 把小于基准数的数都放到基准数之前, 把大于基准数的数都放到基准数之后 Worst case: O(n^2) Average case: O(nlogN) 步骤: 初始的数组 Array a[]: 0 1 2 3 4 5 6 7 8 9 51 73 52 18 91 7 87 73 48 3 基准数: X = a[0] = 51 i 的值: i = 0 j 的值: j = 9 (a.length) Step 1:

快速排序算法回顾 --冒泡排序Bubble Sort和快速排序Quick Sort(Python实现)

冒泡排序的过程是首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换,然后比较第二个记录和第三个记录的关键字.以此类推,直至第n-1个记录和第n个记录的关键字进行过比较为止.上述过程称为第一趟冒泡排序,接着第二趟对前面n-1个关键字进行同样操作,…… 快速排序是对冒泡排序的一种改进,通过一趟排序将记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,可分别对这两部分记录以递归的方法继续进行排序,以达到整个序列有序. 单趟Partition()函数过程请看

基础算法之快速排序Quick Sort

原理 快速排序(Quicksort)是对冒泡排序的一种改进. 从数列中挑出一个元素,称为"基准"(pivot); 排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边).在本次排序退出之后,该基准就处于数列的中间位置.这个称为分区(partition)操作; 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序. 例子 将无序数组[3,6,4,2,5,1]进行快速排序 1),先把第一项[3]取出来作为基准依次

深入解析快速排序(Quick Sort)

本文将对快速排序进行深入的分析和介绍.通过学习本文,您将 秒杀快速排序面试 掌握高效实现快排 加深范型编程意识 八卦花絮 快速排序是由图灵奖获得者.计算机语言设计大佬C. A. R. Hoare在他26岁时提出的.说起C. A. R. Hoare老爷爷,可能很多人的第一印象就是快速排序,但是快排仅仅是他人生中非常小的成就而已.例如,他在1978年提出的Communicating Sequential Processes(CSP)理论,则深深的影响了并行程序设计,Go语言中的Goroutine就是

快速排序Quick sort(转)

原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 举个例子 如无序数组[6 2 4 1 5 9] a),先把第一项[6]取出来, 用[6]依次与其余项进行比较, 如果比[6]小就放[6]前边,2 4 1 5都比[6]小,所以全部放到[6]前边 如果比[6]大就放[6]后边,9比[6]大,放到[6]后边,//6出列后大喝一声,比我小的站前边,比

排序:快速排序Quick Sort

原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 举个例子 如无序数组[6 2 4 1 5 9] a),先把第一项[6]取出来, 用[6]依次与其余项进行比较, 如果比[6]小就放[6]前边,2 4 1 5都比[6]小,所以全部放到[6]前边 如果比[6]大就放[6]后边,9比[6]大,放到[6]后边,//6出列后大喝一声,比我小的站前边,比

笔试算法题(54):快速排序实现之单向扫描、双向扫描(single-direction scanning, bidirectional scanning of Quick Sort)

议题:快速排序实现之一(单向遍历) 分析: 算法原理:主要由两部分组成,一部分是递归部分QuickSort,它将调用partition进行划分,并取得划分元素P,然后分别对P之前的部分和P 之后的部分递归调用QuickSort:另一部分是partition,选取划分元素P(随机选取数组中的一个元素,交换到数组末尾位置),定义两个标记 值left和right,随着划分的进行,这两个标记值将数组分成三部分,left之左的部分是小于划分元素P的值,left和right之间的部分是大 于等于划分元素P的