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

Posted cpp_learner

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

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


总结

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

以上是关于C/C++ 七大排序算法 之 “快速排序”的主要内容,如果未能解决你的问题,请参考以下文章

万字手撕七大排序(代码+动图演示)

C/C++ 七大排序算法 之 “归并排序”

数据结构图解七大排序

七大排序之:冒泡排序和快速排序

Java集合与数据结构——七大排序算法的实现

手撕七大排序