快速排序
Posted 西伯尔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序相关的知识,希望对你有一定的参考价值。
一、概述
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快速:
它是处理大数据最快的排序算法之一了。
快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。
但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。
所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
二、算法步骤
1、pivot
从数列中挑出一个元素,称为 "基准"(pivot);
2、partition
分区(partition)操作:pivot的左小右大。在这个分区退出之后,该基准就处于数列的中间位置。
具体操作方案:
①两个指针left,right
②pivot默认是left的元素
③第一趟从right向左扫描,遇到比pivot小的(右小),把right赋值给left,并换到left向右扫描。
④从left向右扫描,遇到比pivot大的(左大),把left赋值给right,并换到right。
⑤终止条件:while(left<right)
3、递归
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
终止条件:
if (arr == null || left >= right) { return; }
三、例子
参考:
四、代码
package 排序算法; public class ClassicSortMethods { public static void main(String[] args) { int[] arr = {1, 112, -13, 24, -21, 12}; ClassicSortMethods sm = new ClassicSortMethods(); sm.quickSort(arr, 0, arr.length - 1); for (int num : arr) { System.out.print(num + " "); } System.out.println(); } /** * 快速排序: * <p> * 平均快于O(nlogn)的算法 * 大数据最快 * 本质是,在冒泡基础上的递归分治法 * 思想:pivot,小的放前面,大的放后面,分为两部分后递归。 * 如何分成两部分:【好吧,搞半天理解错思路了,好像当成选择排序了。。。,快排要有左右两个指针,来回换着比较,这样才不会丢!】 */ public void quickSort(int[] arr, int left, int right) { if (arr == null || left >= right) { return; } int pivot_index = partition(arr, left, right); quickSort(arr, left, pivot_index - 1); //这里的end应该是pivot,因为end本身取不到值,如果减一会丢掉一个数! quickSort(arr, pivot_index + 1, right); } /** * 分区,走一趟,返回的是pivot的下标。 * 两个指针,分别从左右走,先从右开始,一旦发生交换,就从对侧开始走。 * 直到重合,就把pivot值赋给它,也就是要返回的下标位置。 */ private int partition(int[] arr, int left, int right) { if (arr == null || left >= right) { return -1; } int pivot = arr[left]; while (left < right) { while (left < right && arr[right] >= pivot) { right--; } arr[left] = arr[right]; //右小时,把右边的值赋给left,然后就要从左开始了。 while (left < right && arr[left] <= pivot) { left++; } arr[right] = arr[left];//左大,要吧左边的值赋值给right,然后又要从右开始了。 }//退出循环时,left=right arr[left] = pivot; return left; } }
以上是关于快速排序的主要内容,如果未能解决你的问题,请参考以下文章