【数据结构】排序算法之快速排序(Hoare版)

本文详细介绍了快速排序的基本逻辑,利用分治策略将其分解为层排序和整体排序的过程,比较了与冒泡排序的效率,并提供了代码实现。
摘要由CSDN通过智能技术生成

 引言

快速排序又叫快排,在排序算法中的地位可谓是举足轻重,它是C语言中qsort函数和C++中sort函数的底层排序算法。同时作为与它同为交换排序的冒泡排序,其效率和性能与快排相差很多。本片博客会重点介绍快排的算法逻辑、效率分析以及代码和效率优化。

 快速排序的基本逻辑

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

简单来讲就是:

1.从待排序的元素序列中随机选取一个数,我们称该元素为k。

2.接下来把小于k的放在k的左边,大于k的放在k的右边。

3.最后从k位置分成左右两个序列,左右两个序列重复上述操作,直到有序。

我们可以看出这是一个分治的思想,我们仅需要完成一层排序,剩下的进行递归即可。

快速排序层排序实现

算法实现之前,请大家先看一下如下gif动图的快排层排序实现。

 第一步,选取序列中第一个元素作为基准值,用变量key记录基准值的下标。

第二步,定义两个下标变量,分别为L和R。L是从序列左边走向序列右边,R是从序列右边走向序列左边。

第三步,让R先走,此时就需要讨论R的停止条件。

1.如果R位置的数值比key位置的数值小,R就停下。

2.如果R遇到L,R就停下。

分析R停下来以后的情况。

如果R停下是因为条件一,那么L开始走,L位置的数值直到比key位置的数值大就停下,在L和R位置的数值交换。重复第二步。

如果R停下是因为条件二,那么R(L)位置的数值与key位置的数值交换,然后把L给了key层排序结束。

接下来是代码的实现

void Swap(int* a, int* b)
{
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}
void PartSort(int* a, int L,int R)
{
	int key = L;
	while (L < R)
	{
		while (L < R && a[R] >= a[key])
		{
			R--;
		}
		while (L <R && a[L] <= a[key])
		{
			L++;
		}
		Swap(&a[L], &a[R]);
	}
	Swap(&a[L], &a[key]);
    key=L;
}

 快排的层排序目前已经结束了,接下来是快排的整体排序。

快速排序整体排序算法实现

有了快排层排序算法的基础,快排的整体排序就变得容易许多,接下来要用到分治思想。

在层排序之后,L与R重合,此时应该从重合位置断开,分为左右两个序列,这两个序列的特点分别是左边序列的数均小于重合位置的数值,右边序列的数值均大于重合位置的数值,此时分别对两个序列进行层排序。

对左边序列进行分析,此时的L仍为数组首元素的下标,R为上一层的key-1.

对右边序列进行分析,此时的L为上一层的key+1,R仍为数组的最右端。

下面的快速排序的代码实现

void Swap(int* a, int* b)
{
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}
void QuickSort1(int* a, int left, int right)
{
	
	int begin = left;
	int end = right;
	int keyi = begin;
	if (begin >= end)
		return;
	while (left <right)
	{
		while (left < right && a[right] >= a[keyi])
		{
			right--;
		}
		while (left<right && a[left]<=a[keyi])
		{
			left++;
		}
		Swap(&a[left], &a[right]);
	}
	Swap(&a[keyi], &a[left]);
	keyi = left;
	QuickSort1(a, begin, keyi - 1);
	QuickSort1(a, keyi + 1, end);
}

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值