快速排序算法和原理

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

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

相关文章
|
2月前
|
搜索推荐 C语言
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
65 4
|
3月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
67 3
|
6天前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
33 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
2月前
|
存储 搜索推荐 Python
用 Python 实现快速排序算法。
快速排序的平均时间复杂度为$O(nlogn)$,空间复杂度为$O(logn)$。它在大多数情况下表现良好,但在某些特殊情况下可能会退化为最坏情况,时间复杂度为$O(n^2)$。你可以根据实际需求对代码进行调整和修改,或者尝试使用其他优化策略来提高快速排序的性能
132 61
|
14天前
|
算法 Java 数据库
理解CAS算法原理
CAS(Compare and Swap,比较并交换)是一种无锁算法,用于实现多线程环境下的原子操作。它通过比较内存中的值与预期值是否相同来决定是否进行更新。JDK 5引入了基于CAS的乐观锁机制,替代了传统的synchronized独占锁,提升了并发性能。然而,CAS存在ABA问题、循环时间长开销大和只能保证单个共享变量原子性等缺点。为解决这些问题,可以使用版本号机制、合并多个变量或引入pause指令优化CPU执行效率。CAS广泛应用于JDK的原子类中,如AtomicInteger.incrementAndGet(),利用底层Unsafe库实现高效的无锁自增操作。
理解CAS算法原理
|
2月前
|
算法 容器
令牌桶算法原理及实现,图文详解
本文介绍令牌桶算法,一种常用的限流策略,通过恒定速率放入令牌,控制高并发场景下的流量,确保系统稳定运行。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
令牌桶算法原理及实现,图文详解
|
1月前
|
存储 人工智能 缓存
【AI系统】布局转换原理与算法
数据布局转换技术通过优化内存中数据的排布,提升程序执行效率,特别是对于缓存性能的影响显著。本文介绍了数据在内存中的排布方式,包括内存对齐、大小端存储等概念,并详细探讨了张量数据在内存中的排布,如行优先与列优先排布,以及在深度学习中常见的NCHW与NHWC两种数据布局方式。这些布局方式的选择直接影响到程序的性能,尤其是在GPU和CPU上的表现。此外,还讨论了连续与非连续张量的概念及其对性能的影响。
56 3
|
2月前
|
机器学习/深度学习 人工智能 算法
探索人工智能中的强化学习:原理、算法与应用
探索人工智能中的强化学习:原理、算法与应用
|
2月前
|
负载均衡 算法 应用服务中间件
5大负载均衡算法及原理,图解易懂!
本文详细介绍负载均衡的5大核心算法:轮询、加权轮询、随机、最少连接和源地址散列,帮助你深入理解分布式架构中的关键技术。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
5大负载均衡算法及原理,图解易懂!
|
2月前
|
缓存 算法 网络协议
OSPF的路由计算算法:原理与应用
OSPF的路由计算算法:原理与应用
72 4

热门文章

最新文章

下一篇
开通oss服务