快速排序算法和原理

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

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

相关文章
|
11天前
|
搜索推荐 算法 Java
Java数据结构与算法:排序算法之快速排序
Java数据结构与算法:排序算法之快速排序
|
8天前
|
自然语言处理 算法 搜索推荐
分词算法的基本原理及应用
分词算法的基本原理及应用
|
6天前
|
算法 PHP
【php经典算法】冒泡排序,冒泡排序原理,冒泡排序执行逻辑,执行过程,执行结果 代码
【php经典算法】冒泡排序,冒泡排序原理,冒泡排序执行逻辑,执行过程,执行结果 代码
9 1
|
7天前
|
算法 安全 Java
Java中MD5加密算法的原理与实现详解
Java中MD5加密算法的原理与实现详解
|
13天前
|
存储 算法 C语言
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
|
17天前
|
机器学习/深度学习 数据采集 算法
KNN算法原理及应用(一)
**KNN算法**是一种监督学习的分类算法,适用于解决分类问题。它基于实例学习,无需训练过程,当新样本到来时,通过计算新样本与已有训练样本之间的距离,找到最近的K个邻居,然后根据邻居的类别进行多数表决(或加权表决)来预测新样本的类别。K值的选择、距离度量方式和分类决策规则是KNN的关键要素。KNN简单易懂,但计算复杂度随样本量增加而增加,适用于小规模数据集。在鸢尾花数据集等经典问题上表现良好,同时能处理多分类任务,并可应用于回归和数据预处理中的缺失值填充。
KNN算法原理及应用(一)
|
2天前
|
设计模式 JavaScript 算法
vue2 原理【详解】MVVM、响应式、模板编译、虚拟节点 vDom、diff 算法
vue2 原理【详解】MVVM、响应式、模板编译、虚拟节点 vDom、diff 算法
10 0
|
6天前
|
算法 搜索推荐 C#
|
7天前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的基本原理与应用场景
分词算法在自然语言处理中的基本原理与应用场景
|
8天前
|
自然语言处理 算法 Serverless
详尽分享贝叶斯算法的基本原理和算法实现
详尽分享贝叶斯算法的基本原理和算法实现