快速排序算法和原理

简介: 快速排序算法和原理

1.快速排序原理


该方法的基本思想是:


1.先从数列中取出一个数作为基准数。


2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。


3.再对左右区间重复第二步,直到各区间只有一个数。


最本质的总结:


快速排序,说白了就是给基准数据找其正确索引位置的过程.


如下图所示,假设最开始的基准数据为数组第一个元素23,则首先用一个临时变量去存储基准数据,即tmp=23;然后分别从数组的两端扫描数组,设两个指示标志:low指向起始位置,high指向末尾.


 1dc618a0ed9580ce8bfa6facb208c08f.png

 


首先从后半部分开始,如果扫描到的值大于基准数据就让high减1,如果发现有元素比该基准数据的值小(如上图中18<=tmp),就将high位置的值赋值给low位置 ,结果如下:

 5d4c6812c8535adbb050f4ddf2e1bce8.png


然后开始从前往后扫描,如果扫描到的值小于基准数据就让low加1,如果发现有元素大于基准数据的值(如上图46=>tmp),就再将low位置的值赋值给high位置的值,指针移动并且数据交换后的结果如下:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png


然后再开始从后向前扫描,原理同上,发现上图11<=tmp,则将high位置的值赋值给low位置的值,结果如下:

66ba272a0bfc97be54a5fa679e3d5482.png


然后再开始从前往后遍历,直到low=high结束循环,此时low或high的下标就是 基准数据23在该数组中的正确索引位置.如下图所示.

88b9988b40447cb37c7e3c492d49867f.png


这样一遍走下来,可以很清楚的知道,其实快速排序的本质就是把基准数大的都放在基准数的右边,把比基准数小的放在基准数的左边,这样就找到了该数据在数组中的正确位置.

 以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。


2.代码思路


从上面的过程中可以看到:


①先从队尾开始向前扫描且当low < high时,如果a[high] > tmp,则high–,但如果a[high] < tmp,则将high的值赋值给low,即arr[low] = a[high],同时要转换数组扫描的方式,即需要从队首开始向队尾进行扫描了


②同理,当从队首开始向队尾进行扫描时,如果a[low] < tmp,则low++,但如果a[low] > tmp了,则就需要将low位置的值赋值给high位置,即arr[low] = arr[high],同时将数组扫描方式换为由队尾向队首进行扫描.


③不断重复①和②,知道low>=high时(其实是low=high),low或high的位置就是该基准数据在数组中的正确索引位置…


3.找基准数的索引


再来个图,加深找索引的印象;

1dc618a0ed9580ce8bfa6facb208c08f.png


4.参考代码


import java.util.Arrays;
public class QuickSort {
  public static void main(String[] args) {
  int[] arr = { 49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22 };
  quickSort(arr, 0, arr.length - 1);
  System.out.println("排序后:");
  for (int i : arr) {
    System.out.print(i + "  ");
  }
  }
  private static void quickSort(int[] arr, int low, int high) {
  if (low < high) {
    // 找寻基准数据的正确索引
    int index = getIndex(arr, low, high);
    System.out.println("排序后" + Arrays.toString(arr));
    // 进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序
    //quickSort(arr, 0, index - 1); 之前的版本,这种姿势有很大的性能问题,谢谢大家的建议
    quickSort(arr, low, index - 1);
    quickSort(arr, index + 1, high);
  }
  }
  private static int getIndex(int[] arr, int low, int high) {
  // 基准数据
  int tmp = arr[low];
  while (low < high) {
    // 当队尾的元素大于等于基准数据时,向前挪动high指针
    while (low < high && arr[high] >= tmp) {
    high--;
    }
    // 如果队尾元素小于tmp了,需要将其赋值给low
    arr[low] = arr[high];
    // 当队首元素小于等于tmp时,向前挪动low指针
    while (low < high && arr[low] <= tmp) {
    low++;
    }
    // 当队首元素大于tmp时,需要将其赋值给high
    arr[high] = arr[low];
  }
  // 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
  // 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low]
  arr[low] = tmp;
  return low; // 返回tmp的正确位置
  }
}


运行效果如下:

5d4c6812c8535adbb050f4ddf2e1bce8.png

相关文章
机器学习/深度学习 算法 自动驾驶
1256 0
|
7月前
|
机器学习/深度学习 算法 搜索推荐
从零开始构建图注意力网络:GAT算法原理与数值实现详解
本文详细解析了图注意力网络(GAT)的算法原理和实现过程。GAT通过引入注意力机制解决了图卷积网络(GCN)中所有邻居节点贡献相等的局限性,让模型能够自动学习不同邻居的重要性权重。
1348 0
从零开始构建图注意力网络:GAT算法原理与数值实现详解
|
8月前
|
传感器 算法 定位技术
KF,EKF,IEKF 算法的基本原理并构建推导出四轮前驱自主移动机器人的运动学模型和观测模型(Matlab代码实现)
KF,EKF,IEKF 算法的基本原理并构建推导出四轮前驱自主移动机器人的运动学模型和观测模型(Matlab代码实现)
259 2
|
8月前
|
算法
离散粒子群算法(DPSO)的原理与MATLAB实现
离散粒子群算法(DPSO)的原理与MATLAB实现
398 0
|
9月前
|
机器学习/深度学习 人工智能 编解码
AI视觉新突破:多角度理解3D世界的算法原理全解析
多视角条件扩散算法通过多张图片输入生成高质量3D模型,克服了单图建模背面细节缺失的问题。该技术模拟人类多角度观察方式,结合跨视图注意力机制与一致性损失优化,大幅提升几何精度与纹理保真度,成为AI 3D生成的重要突破。
1193 0
|
9月前
|
算法 区块链 数据安全/隐私保护
加密算法:深度解析Ed25519原理
在 Solana 开发过程中,我一直对 Ed25519 加密算法 如何生成公钥、签名以及验证签名的机制感到困惑。为了弄清这一点,我查阅了大量相关资料,终于对其流程有了更清晰的理解。在此记录实现过程,方便日后查阅。
1201 1
|
10月前
|
消息中间件 存储 缓存
zk基础—1.一致性原理和算法
本文详细介绍了分布式系统的特点、理论及一致性算法。首先分析了分布式系统的五大特点:分布性、对等性、并发性、缺乏全局时钟和故障随时发生。接着探讨了分布式系统理论,包括CAP理论(一致性、可用性、分区容错性)和BASE理论(基本可用、软状态、最终一致性)。文中还深入讲解了两阶段提交(2PC)与三阶段提交(3PC)协议,以及Paxos算法的推导过程和核心思想,强调了其在ZooKeeper中的应用。最后简述了ZAB算法,指出其通过改编的两阶段提交协议确保节点间数据一致性,并在Leader故障时快速恢复服务。这些内容为理解分布式系统的设计与实现提供了全面的基础。
|
10月前
|
存储 算法 安全
Java中的对称加密算法的原理与实现
本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。
699 58
下一篇
开通oss服务