快速排序及三种排序方法 Hoare法/挖坑法/前后指针法

本文深入解析了快速排序算法,包括其核心思想、不同实现方法(如Hoare法、挖坑法和前后指针法),以及完整的代码示例。快速排序是一种高效的排序算法,基于分治策略,通过选择基准元素将数组分为两部分,递归地排序每一部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快速排序

算法思想:基于分治的思想,是冒泡排序的改进型。同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的。
不同的是,冒泡排序在每一轮只把一个元素冒泡到数列的一端,而快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分。
在这里插入图片描述
每次把数列分成两部分,究竟有什么好处呢?
假如给定8个元素的数列,一般情况下冒泡排序需要比较8轮,每轮把一个元素移动到数列一端,时间复杂度是O(n^2)。

Hoare法:
在这里插入图片描述
代码

int  HoareMethod(int *a, int beain, int end)
{
	int key = a[end];
	int keyindex = end;
	while (beain < end)
	{
		while (beain < end&&a[beain] <= key)
			beain++;
		while (beain < end&&a[end] >= key)
			end--;
		swap(&a[beain], &a[end]);
	}
	swap(&a[beain], &a[keyindex]);
	return beain;
}

挖坑法:
挖坑法顾名思义,首先我们从右边先取走一个基准值用于比较的数key,取走后这个数所在的位置就成为了一个坑,然后与Hoare法类似,从左边开始找到一个比key大的数,然后将这个数填到刚在取走的数的位置,现在刚才取走的数的位置又成了一个坑,以此类推
给定原始数列如下,要求从小到大排序:
在这里插入图片描述
首先,我们选定基准元素Pivot,并记住这个位置index,这个位置相当于一个“坑”。并且设置两个指针left和right,指向数列的最左和最右两个元素:
在这里插入图片描述
接下来,从right指针开始,把指针所指向的元素和基准元素做比较。如果比pivot大,则right指针向左移动;如果比pivot小,则把right所指向的元素填入坑中。
在当前数列中,1<4,所以把1填入基准元素所在位置,也就是坑的位置。这时候,元素1本来所在的位置成为了新的坑。同时,left向右移动一位。
在这里插入图片描述
此时,left左边绿色的区域代表着小于基准元素的区域。

接下来,我们切换到left指针进行比较。如果left指向的元素小于pivot,则left指针向右移动;如果元素大于pivot,则把left指向的元素填入坑中。

在当前数列中,7>4,所以把7填入index的位置。这时候元素7本来的位置成为了新的坑。同时,right向左移动一位。
以此类推。
代码如下:

int  PitMethod(int *a, int begin,int end)
{
	int key = a[end];
	int pit = end;
	while (begin < end)
	{
		while (begin < end&&a[begin] <= key)
		{
			begin++;
		}
		a[pit] = a[begin];
		pit = begin;
		while (begin < end&&a[end] >= key)
		{
			end--;
		}
		a[pit] = a[end];
		pit = end;
	}
	a[pit] = key;
	return pit;
}

3.前后指针法
前后指针法是定义两个指针,一个cur指向数组第一个元素的位置,另一个pre指向cur的前一个位置,选取最右边的元素为key,比较cur指向的元素是否小于key,如果小于pre后移一个位置,并于cur所指向的位置的元素进行交换,然后cur后移一个位置,以此类推。
代码如下:

int PrevCurMethod(int* a, int begin, int end)
{
	int pre = begin - 1;
	int cur = begin;
	while (cur < end)
	{
		if (a[cur] < a[end] && ++pre != cur)
			swap(&a[cur], &a[pre]);
		cur++;
	}
	pre++;
	swap(&a[pre], &a[cur]);
	return pre;
}

整体快速排序:

void QuickSort(int *a, int begin, int end)
{
	if (begin >= end)
		return;
	//int keyindex = HoareMethod(a, begin, end); //Hoare法
	//int keyindex = PitMethod(a, begin, end);   //挖坑法
	int keyindex = PrevCurMethod(a, begin, end); //前后指针法
	QuickSort(a, begin, keyindex - 1);
	QuickSort(a, keyindex + 1, end);
	
}
回答: 快速排序Hoare是一种常用的快速排序算法实现方法。它是由Tony Hoare在1960年提出的。Hoare的基本思想是选择一个基准值,将待排序序列分成两部分,一部分是小于基准值的元素,另一部分是大于基准值的元素。然后对这两部分分别进行递归排序,最终将整个序列排序完成。具体实现过程如下: 1. 选择一个基准值,可以是序列中的任意一个元素。 2. 定义两个指针,一个指向序列的起始位置,一个指向序列的末尾位置。 3. 移动指针,直到找到一个大于等于基准值的元素。 4. 移动指针,直到找到一个小于等于基准值的元素。 5. 如果左指针小于等于右指针,则交换左右指针所指向的元素。 6. 继续移动左右指针,直到左指针大于右指针。 7. 将基准值与右指针所指向的元素交换。 8. 分别对基准值左边和右边的子序列进行递归排序。 通过以上步骤,每一次递归都会将基准值放置在正确的位置上,最终完成整个序列的排序。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [【八大排序③】快速排序(动图演绎Hoare挖坑前后指针法)](https://blog.csdn.net/Living_Amethyst/article/details/125513838)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [快速排序常见3种方法(hoare挖坑前后指针法)以及改进。](https://blog.csdn.net/tjh1998/article/details/122159488)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值