C/C++ 七大排序算法 之 “快速排序”

排序:即将一组混乱的数据按从小到大或者从大到小的顺序进行有序的排列出来。

归并排序算法图解:
在这里插入图片描述
网上找的!

思路解答
选取数组中的第一个数作为基数,然后从数组的最右边最后一个数开始寻找一个比他还要小的第一个值,将这个数值复制到基数的位置,然后从最左边寻找还没匹配的数值,寻找比基数要大的第一个数,将这个数赋值给刚才比基数小的数的位置;然后再从左边还没匹配的数中开始寻找第一个比基数要小的数…

执行完这样的步骤后,最后剩余的那个位置,就是基数的位置!

总结下来就是:

  1. 每次选取第一个数为基准数;
  2. 然后使用“乾坤挪移大法”将大于和小于基准的元素分别放置于基准数两边;
  3. 继续分别对基准数两侧未排序的数据使用分治法进行细分处理,直至整个序列有序。

例:
对于下面待排序的数组:

在这里插入图片描述
第一步:先选择第一个数 163 为基准数,以 163 为基准将小于它的数排在它前面,大于等于它
的数排在其后,结果如下:
在这里插入图片描述
他是如何排序成这样的?
其排序过程是这样的!

  1. 确定 163 为基准数后,先把 163 从数组中取出来
    在这里插入图片描述

  2. 然后从最右端开始,查找小于基准数 163 的数,找到 162,将其移至空出来的元素中
    在这里插入图片描述

  3. 接下来,从最左边未处理的元素中从左至右扫描比基数 163 大的数,将其移动至右侧空出来的元素中
    在这里插入图片描述

  4. 接下来,继续从最右边未处理的元素中从右至左扫描比基数 163 小的数,将其移动至左侧空出来的元素中
    在这里插入图片描述

  5. 接下来再重复执行步骤 3,171 执行右移
    在这里插入图片描述

  6. 重复执行步骤 4,此时右边的值已经均大于基数,左边的值均已小于基数
    在这里插入图片描述

  7. 接下来我们将基数保存回黄色空格中
    在这里插入图片描述

第二步:采用分治法分别对基数左边和右边的部分运用第一步中的方法进行递归操作,直到整个数组变得有序,以左边的数组为例:
在这里插入图片描述
代码实现

#include <iostream>
#include <stdio.h>

using namespace std;

// 乾坤大挪移
int Partition(int arr[], int low, int high) {
	int i = low;
	int j = high;
	int base = arr[low];		// 保存基数

	// 合法性检查
	if (low < high) {
		while (i < j) {

			// 从最右边开始寻找比基数小的第一个数的下标
			while (i < j && arr[j] >= base) {
				j--;
			}

			// 在右边已经找到小于基数的一个数
			if (i < j) {
				arr[i] = arr[j];
				i++;	// 基数的位置已经被填充,i要去到下一个位置
			}

			// 从最左i的位置开始寻找比基数大的第一个数的下标
			while (i < j && arr[i] < base) {
				i++;
			}

			// 在左边已经找到大于基数的一个数
			if (i < j) {
				arr[j] = arr[i];
				j--;	// 刚刚小于基数的那个位置已经被填充,j要自减去到上一个位置
			}
		}

		// 当外层while循环结束,说明i等于j,剩余中间的一个位置,就是基数排好序的位置
		arr[i] = base;		// 或者arr[j] = base;
	}	

	return i;
}

// 递归实现快速排序
void QuickSort(int *arr, int low, int high) {

	// 合法性
	if (low < high) {
		int index = Partition(arr, low, high);	// “乾坤大挪移”排序,获得已经排好序的下标

		// 再从排好序下标的左边的数和右边的数进行递归排序
		QuickSort(arr, low, index - 1);
		QuickSort(arr, index + 1, high);
	}
}


int main(void) {
	int arr[] = { 163, 161, 158, 165, 171, 170, 163, 159, 162 };
	int len = sizeof(arr) / sizeof(arr[0]);		// 计算数组的长度

	QuickSort(arr, 0, len - 1);

	printf("执行快速排序后的结果:\n");
	for (int i = 0; i < len; i++) {
		printf(" %d", arr[i]);
	}

	return 0;
}

运行截图:
在这里插入图片描述


总结

选好一个基数,将数组中小于他的值移动到其左边,大于他的值移动到右边。
然后在进行基数左右两边的数组块继续进行同样的排序即可!

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cpp_learners

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

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

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

打赏作者

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

抵扣说明:

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

余额充值