快速排序(Quick Sort)_快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。


1.算法性能

平均时间复杂度 : O(n logn)

最优时间复杂度:  每次选取的基准都是中位数,这样每次都均匀的划分出两个分区,只需要logn次划分就能结束递归,时间复杂度为O(nlogn)

最差时间复杂度: 每次选取的基准都是最大(或最小)的元素,导致每次只划分出了一个分区,需要进行n-1次划分才能结束递归,时间复杂度为O(n^2)

空间复杂度: O(1)

稳定性: 不稳定


2.算法步骤


  1. 从数列中挑出一个元素,称为 “基准”(pivot);
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。


3.Go 代码实现

func _quickSort(arr []int,left,right int) {
if left >=right {
return
}
value := arr[left]
k := left
//确定value所在的位置
for i := left + 1; i <= right; i++ {
//如果右边的数小于value
if arr[i] < value {
//将右边的数移动到value的位置
arr[k] = arr[i]
//把value后一个数移动到右边的数位置
arr[i] = arr[k+1]
//将value的角标+1
k++
//将value赋值到该位置
arr[k] = value
}
}
//递归调用
_quickSort(arr,left,k-1)
_quickSort(arr,k+1,right)
}


4.Java 代码实现

public static void quickSort(int[] arr) {
_quickSort(arr,0,arr.length-1);
}
public static void _quickSort(int[] arr,int left,int right) {
//出口
if (left >=right) {
return;
}
int value = arr[left];
//记录value的角标
int k = left;
//确定value的位置
for (int i = left +1;i<=right;i++) {
if (arr[i] < value) {
//如果右边的数小于value,将右边的数移动到value位置
arr[k] = arr[i];
//将紧邻value右边的数移动到arr[i]的位置
arr[i] = arr[k+1];
//改变value的角标
k++;
//将value赋值到该位置
arr[k] = value;
}
}
//递归调用
_quickSort(arr,left,k-1);
_quickSort(arr,k+1,right);
}