文章目录

  • 快速排序
    • 1 一次快速排序的过程
      • 1.1 图解
      • 1.2 C语言实现
    • 2 快速排序(递归)
      • 2.1 图解
      • 3.2 C语言实现
    • 3 快速排序(非递归)
      • 3.1 图解
      • 3.2 C语言实现

快速排序

定义数组的头部为一个基准,首先从基准的右边比较,交换基准数字;然后从基准的左边比较,交换基准数字。
使基准的左右两边分别都是比基准小和比基准大的数字,完成一次排序。
然后从左右两边分别重新定义新的基准,继续比较排序。
持续减少比较长度,直至左右两边均剩余一个数字,此时完成整个数组的排序。

  • 从小到大进行排序
  • 时间复杂度O( nlog2n )
  • 空间复杂度O( log2n ),不稳定(数据跳跃)
  • 一次快速排序,时间复杂度O(n),递归函数的时间复杂度O( log2n )
  • 数组本身有序,时间复杂度变为O(n2),退化成选择排序

1 一次快速排序的过程

1.1 图解

  • 1、定义一个基准tmp,每次都将下标low的值即arr[low],设定为基准值。
  • 2、首先从下标high开始比较,一直到下标low。
    • 如果arr[high]大于等于基准tmp,且下标low小于下标high,将high向前移动。
    • 如果arr[high]小于基准tmp,将下标high的值arr[high]置于下标low的位置上。
    • 当下标low等于下标high时,说明下标low的右边都是比基准tmp大的数字,此时右边完成交换。
  • 3、然后从下标low开始比较,一直到下标high。
    • 如果arr[low]小于等于基准tmp,且下标low小于下标high,将low向后移动。
    • 如果arr[low]大于基准tmp,将下标low的值arr[low]置于下标high的位置上。
    • 当下标low 等于下标high时,说明下标low的左边都是比基准tmp小的数字,此时左边完成交换。
  • 4、然后将基准值tmp置于下标low的位置上,归位,完成数值交换。此时基准值的两边都是比基准值小或比基准值大的数字

1.2 C语言实现

static int Partition(int* arr,int low,int high)//一次快速排序,时间复杂度O(n)
{int tmp = arr[low];//备份基准值while (low < high)//当low大于等于high时,结束循环{while (low < high && arr[high] >= tmp)//从最后面high开始到low之间,寻找比基准值tmp小的数字,将其移动到前面的空缺位上{high--;//如果arr[high]大于等于基准tmp,向前移动}if (low == high)//当low和high相等时说明没有比基准tmp小的数字,跳出整个循环{break;}else//否则,说明arr[high]小于基准tmp,将high的值置于low的位置上{arr[low] = arr[high];}while (low < high && arr[low] <= tmp)//从最前面low开始到high之间,寻找比基准值tmp大的数字,将其移动到后面的空缺位上{low++;//如果arr[low]大于等于基准tmp,向后移动}if (low == high)//当low和high相等时说明没有比基准tmp大的数字,跳出整个循环{break;}else//否则,说明此位置的arr[low]大于基准tmp,将low的值置于high的位置上{arr[high] = arr[low];}}arr[low] = tmp;//最后将基准值tmp,归位,此时基准值的两边都是比基准值小或比基准值大的数字return low;//返回基准值的位置,用于判断边界
}

2 快速排序(递归)

2.1 图解

  • 首先进行一次快速排序
  • 然后分别判断下标 par(即,基准值所在的下标low) 在整个数组的左右两边的数字个数
    • 如果左右两边剩余的数字个数大于1,就根据下标par给定新的low和high,继续进行左右两边的快速排序。
    • 直至左右两边均剩余一个数字,此时完成整个数组的排序。

3.2 C语言实现

static void Quick(int* arr, int low, int high)//排序边界,递归
{int par = Partition(arr, low, high);if (low + 1 < par)//继续排序划分,直至左边剩余1位数字{Quick(arr, low, par - 1);}if (par < high - 1)//继续排序划分,直至右边剩余1位数字{Quick(arr, par + 1, high);}
}void QuickSort(int* arr, int len)//快速排序(递归)
{Quick(arr, 0, len-1);//调用接口,参数列表不同
}

3 快速排序(非递归)

3.1 图解

  • 首先创建一个大小为4个整型数字的数组缓冲区,用于保存每一次快速排序后,新的下标low和下标high,初始化数组下标top为0。
  • 将下标low和high置于数组的头部和尾部,即0和len-1,执行一次快速排序
  • 然后分别判断下标 par(即,基准值所在的下标low) 在整个数组的左右两边的数字个数,并分别根据下标par给定新的low和high,存入数组缓冲区中
  • 然后依次从缓冲区读取新的low和high,继续进行左右两边的快速排序。
  • 直至左右两边均剩余一个数字,此时数组缓冲区下标越界,说明已完成整个数组的排序。

创建一个大小为4个整型数字的数组缓冲区
因为:每次最多进两组数据,即1个基准的左边和右边都存在超过1个数字需要排序,之后读出数据后再存放数据会直接覆盖,这样可以优先将基准一边的数据先处理完,然后再读出数据处理另一边。

3.2 C语言实现

void QuickSort(int* arr, int len)//快速排序
{int buff[4];//每次最多进两组数据即,1个基准的左边和右边都存在超过1个数字需要排序,之后读出数据后再存放数据会直接覆盖int* stack = buff;assert(stack != NULL);int top = 0;//栈顶指针,当前可以存放数据的下标int low = 0;int high = len - 1;int par = Partition(arr, low, high);while (top >= 0){if (low + 1 < par){stack[top++] = low;stack[top++] = par - 1;}if (par < high - 1){stack[top++] = par + 1;stack[top++] = high;}high = stack[--top];low = stack[--top];if (top < 0){break;}par = Partition(arr, low, high);}
}

排序算法——快速排序(图解+代码)相关推荐

  1. 排序算法——快速排序【代码实现】

    伪代码 function quicksort(array)less, equal, greater := three empty arraysif length(array) > 1 pivot ...

  2. 排序算法 | 快速排序,算法的图解、实现、复杂度和稳定性分析与优化

    今天讲解一下快速排序算法的原理以及实现.复杂度和稳定性分析与优化 目录 1 快速排序的原理 2 快速排序代码实现 3 复杂度和稳定性分析.优化 4 习题练习 1 快速排序的原理 快速排序是所有内部排序 ...

  3. 排序算法 快速排序【详细步骤图解】

    排序算法 快速排序[详细步骤图解] 快速排序 主要思想 图解 第一轮分割序列 第二轮分割序列 --- 左子序列 小结 第三轮分割序列 --- 右子序列 C++实现 总结 快速排序 给定一个序列:22 ...

  4. 快速排序算法(图解+代码)

    快速排序 快速排序是基于交换类的排序.快速排序是当前公认的执行效率最高的排序算法,它的基本思想就是分治思想,使用递归来实现. 下面我们来演示一下快排的大致排序过程. 首先我们给定一个无序数组,将无序数 ...

  5. 【图解算法】排序算法——快速排序

    简介 首先还是得简单的介绍一下快速排序这个算法. 快速排序(Quicksort),又称划分交换排序(partition-exchange sort),一种排序算法,最早由东尼·霍尔提出.在平均状况下, ...

  6. 排序算法10——图解基数排序(次位优先法LSD和主位优先法MSD)

    排序算法1--图解冒泡排序及其实现(三种方法,基于模板及函数指针) 排序算法2--图解简单选择排序及其实现 排序算法3--图解直接插入排序以及折半(二分)插入排序及其实现 排序算法4--图解希尔排序及 ...

  7. python 代码排布_python实现经典排序算法的示例代码

    以下排序算法最终结果都默认为升序排列,实现简单,没有考虑特殊情况,实现仅表达了算法的基本思想. 冒泡排序 内层循环中相邻的元素被依次比较,内层循环第一次结束后会将最大的元素移到序列最右边,第二次结束后 ...

  8. 【排序算法】图解直接插入排序(图解堪比Debug显示每次循环结果)

    [排序算法]图解直接插入排序(图解堪比Debug分析每次循环结果) 写在前面: 本文主要介绍直接插入排序算法,通过图片一步步解释每一趟每一次的后移.代码通过C#实现,并输出每一次交换的情况和比较次数, ...

  9. 【排序算法】图解简单选择排序(图解堪比Debug显示每次循环结果)

    [排序算法]图解简单选择排序(图解堪比Debug分析每次循环结果) 写在前面: 本文主要介绍简单选择排序算法,通过图片一步步解释每一趟每一次的后移.代码通过C#实现,并输出每一次交换的情况和比较次数, ...

  10. 排序算法 快速排序 python 0913

    排序算法 快速排序 python 0913 快速排序 思路 定义快排方法 接收参数:原始列表,起始位置,终止位置 判断是否符合快排条件,当起始下标与终止下标相等时,代表只有一个元素,无法排序,退出 一 ...

最新文章

  1. c 使用matlab引擎,[转载]C与MATLAB混合编程之调用MATLAB引擎
  2. java mapreduce 标准差_MapReduce设计模式之概要设计模式
  3. PaddleHub教程合集
  4. 电脑一般预装access吗_我作为一名财务人员学Access的经历
  5. 《嵌入式系统Linux内核开发实战指南(ARM平台)》书评
  6. Linux进程地址空间布局
  7. 基于单片机的电子秤系统设计(电路+流程)
  8. rgba通道转rgb_JS实现颜色的10进制转化成rgba格式的方法
  9. 《ABAQUS 6.14超级学习手册》——1.5 ABAQUS帮助文档
  10. vue项目element-ui中el-select回车键隐藏下拉框,实现按回车键查询
  11. SMOTE算法原理 易用手搓小白版 数据集扩充 python
  12. 【UCSC Genome Browser】- Genes and Gene Predictions - NCBI RefSeq
  13. 天朝的单行道+csuoj+spfa算法求最短路
  14. python描述数据维度的含义_NumPy中的维度(dimension)、轴(axis)、秩(rank)的含义
  15. Java并发机制的底层实现原理--volatile
  16. 阿里P6和P7待遇差别有多大网友干的活差不多,工资差很多
  17. linux红帽修改默认字体大小,为 Redhat Linux 添加新字体
  18. Win10卸载微软sql服务器,win10系统彻底卸载server 2008数据库的设置办法
  19. CISP-PTE、CISP、CISSP之间的区别
  20. 一个人,向南走了一公里,然后向东走1公里,然后向北走一公里

热门文章

  1. Python 调用动态链接库
  2. C# 获取适配器网络连接IP地址,子网掩码,DNS,数据包等信息
  3. 移植智能ABC输入法到Windows XP
  4. 当使用curl 下载压缩包时报解压格式错误
  5. CodeForces - 616C The Labyrinth dfs+暴力
  6. linux模糊查找目录文件,详解Linux查找目录下的按时间过滤的文件
  7. 反向传播算法推导、激活函数、梯度消失与爆炸
  8. react render相关 【类组件、函数组件 】
  9. 使用redis incr处理并发问题
  10. MacOS任意降级(完美教程)