算法概念
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n2),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:
快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
实现
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个元素)作为基准点,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序,然后采用递归调用,分别以同样的方式排序前面和后面的数据。
值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
快速排序实现步骤
- 确定任何值为列表的主元(通常是最后一个值)。假设有两个值“Low”和“High”对应第一个索引和最后一个索引。
- 这里使用的方法是在每次分割时递归,以获得单元素数组。
- 在每一次分割,pile被分割,然后同样的方法被用于较小的pile。
- 由于这些特性,快速排序也称为分区交换排序。
实现图解
快速排序伪代码
/* low --> index起始, high --> index结尾 */
quickSort(arr[], low, high)
{
if (low < high)
{
/* pi为分区指数,arr[pi]为现在在恰好的的地方 */
pi = partition(arr, low, high);
quickSort(arr, low, pi - 1); // 再pi之前
quickSort(arr, pi + 1, high); // 在pi之后
}
}
Java实现代码
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
class QuickSort
{
/** 该函数以最后一个元素为主元素,将主元素放在正确的位置位置在排序的数组,并位置所有
* 比枢轴小的向左的把所有大的元素都向右转*/
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low-1); // 最小元素的指针
for (int j=low; j<high; j++)
{
// 如果当前元素小于等于轴的值
if (arr[j] <= pivot)
{
i++;
// 将arr[i]与arr[j]交换
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 将arr[i+1]和arr[high](或者pivot)交换
int temp = arr[i+1];
arr[i+1] = arr[high];
arr[high] = temp;
return i+1;
}
/*
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void Quick_Sort(int arr[], int low, int high)
{
if (low < high)
{
/* pi为分区指标,arr[pi]为现在在正确的地方 */
int pi = partition(arr, low, high);
// 递归排序之前的元素
// 分区和分区后
Quick_Sort(arr, low, pi-1);
Quick_Sort(arr, pi+1, high);
}
}
/* 打印大小为n的数组的实用函数 */
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i]+" ");
System.out.println();
}
// 驱动程序
public static void main(String args[])
{
int arr[] = {10, 7, 8, 9, 1, 5};
int n = arr.length;
QuickSort ob = new QuickSort();
ob.Quick_Sort(arr, 0, n-1);
System.out.println("sorted array");
printArray(arr);
}
}
}
参考
https://www.runoob.com/w3cnote/quick-sort-2.html
https://blog.youkuaiyun.com/min996358312/article/details/65443400
https://blog.youkuaiyun.com/gg543012991/article/details/52015181