• 【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】


    目录

    前言

    1.冒泡排序

    1.1冒泡排序动图

    1.2冒泡排序源代码

    1.3冒泡排序的特性总结

    2.快速排序👑

    2.1hoare版本实现思想

    排序前

    排序中

    排序后

    2.2hoare版本快排源代码

    2.3分析先走

    情况1🥇

    情况2🥈


    前言

    交换类排序两个常见的排序算法【冒泡排序】、【快速排序】


    交换排序基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。


    交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。


    1.冒泡排序

    1.1冒泡排序动图

    冒泡排序动图

    1.2冒泡排序源代码

    1. void BubbleSort(int* a, int n)
    2. {
    3. assert(a);
    4. for (int j = 0; j < n - 1; ++j)
    5. {
    6. int exchange = 0;//这里的exchange的值作为是否交换的标志
    7. for (int i = 1; i < n - j; ++i)
    8. {
    9. if (a[i - 1] > a[i])
    10. {
    11. Swap(&a[i - 1], &a[i]);
    12. exchange = 1;
    13. }
    14. }
    15. if (exchange == 0)//一趟下来exchange的值还为0,证明就没有发生交换,也就是已经有序
    16. {
    17. break;
    18. }
    19. }
    20. }

    1.3冒泡排序的特性总结

    1. 冒泡排序是一种非常容易理解的排序
    2. 时间复杂度: O(N^2)   最坏O(N^) 、最好O(N)
    3. 空间复杂度: O(1)
    4. 稳定性:稳定


    2.快速排序👑

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

    2.1hoare版本实现思想


    排序前


    排序中

    ①先选出一个基准值key(一般是最左边或者最右边) 

    ②然后右边【L】先走找比key小的值,找到了就停下,然后再左边找比key大的值,找到了也停下

    ③然后交换这两个数
    经过上面三步,就动图就变成了下面的样子

    🥇

    🥈


    排序后

    由于是一个一个先走一个后走,肯定会出现相遇的时候,相遇就停下来。相遇后将相遇坐标的值和基准值key交换,这时就完成了单趟的hoare排序


    【这时的key其实就是在正确的位置上了】


    相遇时如下图

    🥉


    2.2hoare版本快排源代码

    1. void QuickSort(int* a, int begin, int end)
    2. {
    3. // 区间不存在,或者只有一个值则不需要在处理
    4. if (begin >= end)
    5. {
    6. return;
    7. }
    8. int left = begin, right = end;
    9. int keyi = left;
    10. while (left < right)
    11. {
    12. // 右边先走,找小
    13. while (left < right && a[right] >= a[keyi])
    14. {
    15. --right;
    16. }
    17. // 左边再走,找大
    18. while (left < right && a[left] <= a[keyi])
    19. {
    20. ++left;
    21. }
    22. Swap(&a[left], &a[right]);
    23. }
    24. Swap(&a[keyi], &a[left]);
    25. keyi = left;
    26. // [begin, keyi-1] keyi [keyi+1, end]
    27. QuickSort(a, begin, keyi - 1);
    28. QuickSort(a, keyi+1, end);
    29. }

    2.3分析先走

    为什么左边做key,右边先走。
    右边做key,左边先走。
    这样就可以保证相遇位置的值小余或者等于key


    我这边拿左边做key,右边先走的情况来讲解。

    情况1🥇

     这个情况比较好理解,就是上面最后相遇位置的值,也就是3,比6要小


    情况2🥈

     这个情况如下图所示

    这边也可以去画一下左边做key,左边先走的情况,会发现相遇位置的值不能保证比key要小



    如果觉得文章不错,期待你的一键三连哦,你个鼓励是我创作的动力之源,让我们一起加油,顶峰相见!!!

                                             🥇下期预告:快排的其他版本和非递归版本🥇

  • 相关阅读:
    剑指offer(C++)-JZ67:把字符串转换成整数atoi(算法-模拟)
    判断num是不是2的某次方
    C++经典41问(2个小时快速掌握C++)
    上海亚商投顾:沪指高开高走 锂电等新能源赛道大反攻
    多线程详解(三)
    考研408-计算机网络 第一章-计算机网络体系结构学习笔记及习题
    医院陪诊系统:改善患者体验的技术创新
    大学生《Web课程谁》期末网页制作 HTML+CSS+JavaScript 网页设计实例 瑜伽网站企业网站制作
    C#通过FTP与异构系统实现业务接口
    基于C语言设计的植物大战僵尸小游戏
  • 原文地址:https://blog.csdn.net/qq_58286439/article/details/131743321