概览
定义
快速排序(英语:Quicksort),又称分区交换排序(partition-exchange sort),简称快排,一种排序算法,最早由东尼·霍尔提出。在平均状况下,排序
快速排序(Quicksort)是对冒泡排序的一种改进。 快速排序由C. A. R.Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
对有序排序
时间复杂度
时间复杂度和层数相关
最好时间复杂度=O(nlog2n),最坏时间复杂度=O(n2)。日常数据都是随机的,所有快速排序法基本都是处于最好的时间复杂度。
最差的情况
若初始序列有序或逆序,则快速排序的性能最差(因为每次选择的都是最靠边的元素)。
最坏情况的解决方案: 中轴的选取方式。
最好的情况
若每一次选中的“枢轴”将待排序序列划分为均匀的两个部分,则递归深度最小,算法效率最高
空间复杂度
空间复杂度和层数相关
首先就地快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;
最优的情况下空间复杂度为:O(logn) ;每一次都平分数组的情况
最差的情况下空间复杂度为:O( n ) ;退化为冒泡排序的情况
最好空间复杂度=O(nlog2n),最坏空间复杂度=O(n2)
快速排序法和二叉树
稳定性
快速排序法是不稳定的
执行步骤
以首元素为轴,将数组分成两部分。再递归的方式迭代排序两边的数组。
C#代码
应用最广,所以必须会手写
/// <summary>
/// 快速排序法
/// </summary>
/// <param name="array"></param>
/// <param name="startIndex"></param>
/// <param name="endIndex"></param>
public static void QuickSort(int[] array, int startIndex, int endIndex)
{
if (startIndex >= endIndex) return;
//中枢,独立一个函数,方便栈回收,降低栈的空间
int pivot = QuickSortCore(array, startIndex, endIndex);
//对中枢左右两边排序
QuickSort(array, startIndex, pivot - 1);
QuickSort(array, pivot + 1, endIndex);
///
}
public static int QuickSortCore(int[] array, int startIndex, int endIndex)
{
/// 方式一
int low = startIndex;
int high = endIndex;
int povit = array[startIndex];
while (low<high)
{
//low和中枢对比
while (array[high] >= povit && low < high)
{
--high;
}
array[low] = array[high];
//low 必须再下面
while (array[low] <= povit && low<high)
{
++low;
}
array[high] = array[low];
}
array[low] = povit;
return low;
}
n {\displaystyle n}
个项目要 O ( n log n ) {\displaystyle \ O(n\log n)}
(大O符号)次比较。在最坏状况下则需要 O ( n 2 ) {\displaystyle O(n^{2})}
次比较,但这种状况并不常见。事实上,快速排序 Θ ( n log n ) {\displaystyle \Theta (n\log n)}
通常明显比其他算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地达成。