排序——简单的快速排序流程(带图例演示)

快速排序(Quicksort),又称划分交换排序(partition-exchange sort),简称快排。它的原理和冒泡排序法一样都是用交换的方式,不过他会在数据中找到一个虚拟的中间值,把小于中间值的数据放在左边,把大于中间值的数据放在右边,再以同样的方式分别处理两边的数据,直到完成排序为止。

执行流程为:

  1. 先以第一个值为基准值,设置其索引为par,将这个值放入一个临时变量tmp中,防止在后面的步骤中被覆盖。再设置第一个值得索引为low,最后一个值的索引为high。先由high的位置开始,由后向前,若找到的数字大于基准值,继续向前找,直到找到小于基准值的值,将它放到索引为low的位置;
  2. 再由low位置从前往后查找查找,若找到的数字小于基准值,继续向后查找,直到找到大于基准值的值,将它放在此时的索引为high的位置;
  3. 步骤2-3都是在low<high的前提下进行,low在不断增大,high在不断减小,直到两者重合,即low=high时,将临时变量tmp中的值,即基准值放入这个位置,此时,这个位置前面的数字都必定比它小,后面的数字都必定比它大,这样,一次排序完成;
  4. 接下来对基准值左右两边的子序列进行同样的处理,直到某一次得到的基准值左右两边都只剩0个或一个数字,此时这组数字已经全部处于有序状态,快速排序完成;

以一组数据:28 6 40 2 60 9 58 16 47 20为例演示一下这个过程:

1)先将第一个数字的索引设置为per,将其复制一份到tmp临时变量中,再设置low为这个数的索引,high为最后一个数的索引;
第一步
2)由high位置开始从后往前查找,发现high对应的值20小于per对应的值28,故将其复制到low的位置
第二步
3)接着从low位置开始由前往后查找,20和6都小于per对应的值28,继续向前查找,直到找到大于28的数字40,将40放到high的位置;
第三步
4)再从high位置往前查找,找到小于per对应的值28的数字16,将其放到low的位置;
第四步
5)由low位置开始由前往后查找,找到大于per对应的值28的数字63,将其放到high的位置;
第五步
6)由high位置开始由后往前查找,找到小于per对应的值28的数字9,将其放到low的位置;
第六步
7)继续从low位置开始从前往后查找,走了一步之后就发现low与high的位置重合,此时将tmp中存储的值28放入该位置,2此时8的最终位置确定,它前面的数字都小于它,后面的数字都大于它,第一轮排序完成;
第一步
8)开始递归的处理28左右两侧的子序列,同上边的步骤一样,先将20放入tmp,从后往前比较后将9放到low位置;
第八步
9)从low位置往后查找,发现这个序列中的数字都小与per对应的值20,直到与high相遇,将tmp中的值放到相遇的位置,20的最终位置确定,再处理其左侧的子序列;
第9步
10)过程不再详述,20左侧子序列处理后的的结果为:
第10步
10)由于这次的基准值9右侧只有一个数字,所以不用再做处理,左侧有两个数字,再进行一次处理,结果为:
第10步
11)再对第一次的基准值28右侧的子序列进行排序,过程不再详述,剩余步骤每次的结果为:
在这里插入图片描述
在这里插入图片描述
至此,数组完全有序,快速排序完成。

  • 10
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用通用算法 partition 实现快速排序的程序: ```c++ #include <iostream> #include <algorithm> #include <vector> using namespace std; int partition(vector<int>& nums, int left, int right) { int pivot = nums[left]; int i = left + 1, j = right; while (i <= j) { if (nums[i] <= pivot) { i++; } else if (nums[j] > pivot) { j--; } else { swap(nums[i], nums[j]); } } swap(nums[left], nums[j]); return j; } void quickSort(vector<int>& nums, int left, int right) { if (left >= right) return; int pivotIndex = partition(nums, left, right); quickSort(nums, left, pivotIndex - 1); quickSort(nums, pivotIndex + 1, right); } int main() { vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3}; quickSort(nums, 0, nums.size() - 1); for (int num : nums) { cout << num << " "; } cout << endl; return 0; } ``` 在这个程序中,`partition` 函数使用了双指针的方法,将数组划分成两个部分,左边的部分都小于等于基准值,右边的部分都大于基准值。最终返回基准值的位置。 `quickSort` 函数则是基于分治思想,将数组分成两个部分分别进行快排,直到数组长度为 1 或 0,然后合并结果。 在主函数中,我们首先定义一个测试数组,然后调用 `quickSort` 函数进行排序,最后输出排序结果。 对于测试数组 `{3, 1, 4, 1, 5, 9, 2, 6, 5, 3}`,快排的过程如下: 1. 初始数组:`3, 1, 4, 1, 5, 9, 2, 6, 5, 3` 2. 第一次划分:选择 `pivot` 为 `3`,将数组划分为 `[1, 1, 2]`, `[3]`, `[4, 5, 9, 6, 5]`,交换 `pivot` 和 `2` 的位置,数组变为 `2, 1, 4, 1, 5, 9, 3, 6, 5, 3`。 3. 对左右两个子数组进行快排: - 左边的子数组 `[2, 1, 4, 1, 5, 3, 5, 3]`,选择 `pivot` 为 `2`,划分为 `[1, 1]`, `[2]`, `[4, 5, 3, 5, 3]`,交换 `pivot` 和 `1` 的位置,数组变为 `1, 1, 2, 4, 5, 3, 5, 3`,然后对左右两个子数组继续进行快排。 - 右边的子数组 `[9, 6]`,选择 `pivot` 为 `9`,划分为 `[]`, `[9]`, `[6]`,不需要进行快排。 4. 最终数组:`1, 1, 2, 3, 3, 4, 5, 5, 6, 9`

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值