C++数据结构:排序(下)(快速排序的三种方法)

目录

快速排序(我们说的都是升序,降序就把符号反过来)

填坑法!

前后指针法

单向扫描排序


快速排序(我们说的都是升序,降序就把符号反过来)

填坑法!

假如说我现在有数组{ 5,1,4,7,8,2,3,6,9,0 },将begin指向5的索引(数组中第一个索引),end指向0的索引(数组中最后一个位置),先挖了第一个数当坑,然后被挖的数我们当作关键数

我们通过控制begin和end的移动,让begin往右走,left往左走来进行一系列的交换,让关键数放到begin=end的位置

最后我们想要的结果是这样的

关键数的左边都是比5要小,关键数右边都比5要大,那经过怎么个流程才能达到这种效果呢?

流程:因为我们先挖的最左边的数,我们就先动右边的end,让end往左边走,找比5要小的数,放到坑中

放进去之后,我们发现end的地方就会出现坑,那我们就动begin,让begin往左边走找比关键数大的数放到坑中

放进去begin的位置就会出现坑,那就让end往前走去找比关键数小的数去填坑,总之如果begin出现坑那就让end找比key小的数填,end出现坑那就让begin找比关键数大的数去填

最后begin会和end重合,把key放到begin和end重合的位置

我们看代码

void QuickSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	int key = a[begin];
	int privot = begin;
	while (begin < end)
	{
		while (begin<end&&a[end] > key)
		{
			end--;
		}
		privot = end;
		a[begin] = a[end];
		begin++;
		while (begin < end && a[begin] < key)
		{
			begin++;
		}
		privot = begin;
		a[end] = a[begin];
		end--;
	}
	a[begin] = key;
}

我们用递归来实现两边的

#include<iostream>
using namespace std;
void QuickSort(int* a, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	int begin = left;
	int end = right - 1;
	int key = a[begin];
	int privot = begin;
	while (begin < end)
	{
		while (begin<end && a[end] > key)
		{
			end--;
		}
		a[begin] = a[end];
		privot = end;
		//begin++;
		while (begin < end && a[begin] < key)
		{
			begin++;
		}
		a[end] = a[begin];
		privot = begin;
		//end--;
	}
	a[begin] = key;
	privot = begin;
	QuickSort(a, left, privot);
	QuickSort(a, privot + 1, right);
}
int main()
{
	int a[] = { 5,1,4,7,8,2,3,6,9,0 };
	int n = sizeof(a) / sizeof(int);
	QuickSort(a, 0, n);
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
	return 0;
}

key的官方给值的方法是三数取中(左边,右边,中间排好序之后取中间的数)

前后指针法

假如说我们有一个数组{4,5,9,8,7,6,3,0,1,2},我们进行排序,先说一下什么是前后指针排序,顾名思义就是设置一个快指针和一个慢指针

我们设置cur为快指针,prev为慢指针,cur每回往前走一步,如果找到比key小的数,就让prev+1之后和cur交换位置,知道cur超出数组范围之后就结束,然后让key和prev指向元素互换位置

我们来模拟一遍这个过程

cur往前找到了比key小的数了

prev+1,然后进行元素互换

交换完位置后

然后接着让cur往前走,找下一个比key小的数,重复上面的操作,下面是我们cur走到数组末尾的图

然后让prev和key交换位置

这就是前后指针来进行第一趟排序

然后我们看代码

#include<iostream>
using namespace std;
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
void QuickSort(int* a, int n)
{
	int begin = 0;
	int cur = begin;
	int prev = begin;
	int key = a[begin];
	cur += 1;
	while (cur < n-1)
	{
		while (a[cur] > key)
		{
			cur++;
		}
		prev++;
		Swap(&a[prev], &a[cur]);
	}
	Swap(&a[prev], &a[begin]);
}
int main()
{
	int a[] = { 4,5,9,8,7,6,3,0,1,2 };
	int n = sizeof(a) / sizeof(int);
	QuickSort(a, n);
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
	return 0;
}

单向扫描排序

#include<iostream>
#include<stdlib.h>
#include<stdbool.h>
#include<string>
#include<vector>
using namespace std;
//快排:单向扫描
void Swap(int* a, int* b)//交换两个值的函数
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int partition(int* a, int p, int r)//一次扫描函数
{
	int key = a[p];
	int pivot = p;
	int scanner = p + 1;
	int bigger = r;
	while (scanner <= bigger)//让一个scanner往前扫描
	{
		if (a[scanner] <= key)//如果扫描的值小于key值,
			                  //我们让scanner指针向后走一个
		{
			scanner++;
		}
		else if (a[scanner] > key)//如果扫描的值大于key值
		{
			Swap(&a[scanner], &a[bigger]);//交换元素
			                              //我们把比key大的元素放到右边
			bigger--;                     //bigger向前移动一位
		}
	}
	Swap(&a[p], &a[bigger]);
	return bigger;
}
void QuickSort(int* a, int p, int r)
{
	if (p < r)
	{
		int q = partition(a, p, r);
	    QuickSort(a, q + 1,r);
	    QuickSort(a, p, q - 1);
	}
}
int main()
{
	int a[] = { 7,8,5,4,1,3,6,2,9,0 };
	int n = sizeof(a) / sizeof(int);
	QuickSort(a, 0, n - 1);
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值