C++快排 ~ 三种实现方法

1、前言

快排的理论部分,有兴趣者可点击博客 温故而知新 -> 数据结构 ->排序 或通过其他方式进行理解!
博主其实之前实现过快排,具体可见博客 温故而知新 -> 数据结构 ->排序 ->程序实现2_利用C++ 中的内容,但因为当时实现是函数之间的层层调用,虽然理解不难,但代码量会比较多,也有点麻烦,所以在本篇博客中将对其进行精简!

快排中,将区间按照基准值划分为左右两半部分的常见方式有:

  1. hoare版本
  2. 挖坑法
  3. 前后指针版本

所以下面的程序实现将按这三种方法进行说明!

2、代码

2.1 hoare 版本

2.1.1 代码

#include <iostream>
#include <vector>
using namespace std;

void display(vector<int>& arr)
{
	for (auto& n : arr)
		cout << n << " ";
	cout << endl;
}
// 将数组以升序进行排列!
void quickSort(vector<int>& arr, int left, int right) // hoare  升序
{
	if (left >= right)
		return;
	int key = arr[left];
	int begin = left;
	int end = right;
	int start = left;
	while (begin < end)
	{
		while (begin < end && arr[end] >= key)
			--end;
		while (begin < end && arr[begin] <= key)
			++begin;
		if (begin != end)//此句是用于减少不必要的操作,可加可不加
			swap(arr[begin], arr[end]);
	}
	swap(arr[start], arr[begin]);
	quickSort(arr, left, begin - 1);//此处begin与end可任选其一
	quickSort(arr, begin + 1, right);
}
// 将数组以降序进行排列!
void quickSort_2(vector<int>& arr, int left, int right) // hoare  降序
{
	if (left >= right)
		return;
	int key = arr[left];
	int begin = left;
	int end = right;
	int start = left;
	while (begin < end)
	{
		while (begin < end && arr[end] <= key)
			--end;
		while (begin < end && arr[begin] >= key)
			++begin;
		if (begin != end)//此句可加可不加
			swap(arr[begin], arr[end]);
	}
	swap(arr[start], arr[begin]);
	quickSort_2(arr, left, begin - 1);//此处begin与end可任选其一,因为上面的循环结束后,begin会与end相等
	quickSort_2(arr, begin + 1, right);
}
void test()
{
	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
	cout << "原数组:"; display(arr);
	quickSort(arr, 0, arr.size() - 1);
	cout << "升序排列:"; display(arr);
	quickSort_2(arr, 0, arr.size() - 1);
	cout << "降序排列:"; display(arr);
}

int main()
{
	test();
	return 0;
}

注意:上述升序与降序的主要区别就是程序中的大小判断条件相反!

2.1.2 运行结果

在这里插入图片描述

2.2 挖坑法

2.2.1 代码

#include <iostream>
#include <vector>
using namespace std;

void display(vector<int>& arr)
{
	for (auto& n : arr)
		cout << n << " ";
	cout << endl;
}
// 将数组以升序进行排列!
void quickSort2(vector<int>& arr, int left, int right) 
{
	if (left >= right)
		return;
	int key = arr[left];
	int begin = left;
	int end = right;
	while (begin < end)
	{
		while (begin < end && arr[end] >= key)
			--end;
		arr[begin] = arr[end];//此处其实也可通过判断begin与end是否相等来减少多余操作
		while (begin < end && arr[begin] <= key)
			++begin;
		arr[end] = arr[begin];//此处其实也可通过判断begin与end是否相等来减少多余操作
	}
	arr[begin] = key;
	quickSort2(arr, left, end - 1);
	quickSort2(arr, end + 1, right);
}
// 将数组以降序进行排列!
void quickSort2_2(vector<int>& arr, int left, int right)
{
	if (left >= right)
		return;
	int key = arr[left];
	int begin = left;
	int end = right;
	while (begin < end)
	{
		while (begin < end && arr[end] <= key)
			--end;
		arr[begin] = arr[end];//此处其实也可通过判断begin与end是否相等来减少多余操作
		while (begin < end && arr[begin] >= key)
			++begin;
		arr[end] = arr[begin];//此处其实也可通过判断begin与end是否相等来减少多余操作
	}
	arr[begin] = key;
	quickSort2_2(arr, left, begin - 1);
	quickSort2_2(arr, begin + 1, right);
}
void test()
{
	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
	cout << "原数组:"; display(arr);
	quickSort2(arr, 0, arr.size() - 1);
	cout << "升序排列:"; display(arr);
	quickSort2_2(arr, 0, arr.size() - 1);
	cout << "降序排列:"; display(arr);
}

int main()
{
	test();
	return 0;
}

2.2.2 运行结果

在这里插入图片描述

2.3 前后指针

2.3.1 代码

#include <iostream>
#include <vector>
using namespace std;

void display(vector<int>& arr)
{
	for (auto& n : arr)
		cout << n << " ";
	cout << endl;
}
// 将数组以升序进行排列!
void quickSort3(vector<int>& arr, int left, int right)
{
	if (left >= right)
		return;
	int prev = left;
	int cur = left + 1;
	int key = arr[left];
	while (cur <= right)
	{
		if (arr[cur] < key && ++prev != cur)//小于基准值且不连续时进行交换
			swap(arr[prev], arr[cur]);
		++cur;
	}
	swap(arr[left], arr[prev]);
	quickSort3(arr, left, prev - 1);
	quickSort3(arr, prev + 1, right);
}
// 将数组以降序进行排列!
void quickSort3_2(vector<int>& arr, int left, int right)
{
	if (left >= right)
		return;
	int prev = left;
	int cur = left + 1;
	int key = arr[left];
	while (cur <= right)
	{
		if (arr[cur] > key && ++prev != cur)//小于基准值且不连续时进行交换
			swap(arr[prev], arr[cur]);
		++cur;
	}
	swap(arr[left], arr[prev]);
	quickSort3_2(arr, left, prev - 1);
	quickSort3_2(arr, prev + 1, right);
}
void test()
{
	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
	cout << "原数组:"; display(arr);
	quickSort3(arr, 0, arr.size() - 1);
	cout << "升序排列:"; display(arr);
	quickSort3_2(arr, 0, arr.size() - 1);
	cout << "降序排列:"; display(arr);
}

int main()
{
	test();
	return 0;
}

2.3.2 运行结果

在这里插入图片描述
上述三种方法,个人推荐用第二种~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值