常见的排序—交换排序

3 交换排序

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。
3.1冒泡排序
冒泡排序是一种非常容易理解的排序 我们第一个接触的排序方法就是冒泡排序。

基本思路就是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。需要注意的是我们需要挪动n-1次(n-1个数外层循环),因为最后一次不用挪动;内层循环一个数挪动次数比上一次少一次(数与数之间的比较)。
例如:
在这里插入图片描述
通过调试我们知道结果是:
在这里插入图片描述
代码:

void Swap(HPDataType* p1, HPDataType* p2)
{
	HPDataType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void BubbleSort(int* a, int n)
{
	assert(a);

	for (int i = 0; i < n - 1; ++i)
	{
		for (int j = 0; j < n - 1 - i; ++j)
		{
			if (a[j] > a[j + 1])
			{
				Swap(&a[j], &a[j + 1]);
			}
		}

	}
}

我们可以稍微改进一下,万一有一次排序后剩下的刚好有序就跳出来(例如:912345678当九排序后就有序了我们就不需要接着排序了)
改进代码:

void Swap(HPDataType* p1, HPDataType* p2)
{
	HPDataType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void BubbleSort(int* a, int n)
{
	assert(a);

	for (int i = 0; i < n - 1; ++i)
	{
		int flag = 0;
		for (int j = 0; j < n - 1 - i; ++j)
		{
			if (a[j] > a[j + 1])
			{
				flag = 1;
				Swap(&a[j], &a[j + 1]);
			}
		}

		if (!flag)
		{
			break;
		}

	}
}

3.2 快速排序

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

框架:

// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int array[], int left, int right)
{
	if (right - left <= 1)
		return;
	// 按照基准值对array数组的 [left, right)区间中的元素进行划分
	int div = partion(array, left, right);
	// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)
	// 递归排[left, div)
	QuickSort(array, left, div);
	// 递归排[div+1, right)
	QuickSort(array, div + 1, right);
}

上述为快速排序递归实现的主框架,发现与二叉树前序遍历规则非常像,友友们在写递归框架时可想想二叉树前序遍历规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可。
在这里插入图片描述

void Swap(HPDataType* p1, HPDataType* p2)
{
	HPDataType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void QuickSort(int* a, int begin, int end)
{
	assert(a);

	if (begin >= end)
		return;

	int left = begin;
	int right= end;
	int key = left;
	while (left < right)
	{
		//右边先走,找小
		while (left < right && a[right] >= a[key])
			--right;
		//左边再走,找大
		while (left < right && a[left] <= a[key])
			++left;

		Swap(&a[right], &a[left]);

	}
	Swap(&a[key], &a[left]);

	QuickSort(a, begin, left - 1);
	QuickSort(a, left + 1, end);

}

初始:
在这里插入图片描述
第一次走完时:
在这里插入图片描述

排序后结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昨天;明天。今天。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值