Quick Sort (快速排序)
GeesforGeeks Quick Sort博文,包括视频、算法复杂度分析,C C++ Java Python C#的实现版本
单词
- pivote 中心点
- partition 分开、划分、分隔
- Divide and Conquer algorithm 分治算法
- 例如:Quick Sort, Merge Sort
- array中选一个元素作为 pivot
- 将pivot左右 分割(Partition)成两个子array
- permutation 排列
算法步骤
- 选取pivot
- array中第一个元素(index=0)
- 中间元素(index = length/2)
- 最后元素 (index = length - 1)
- 随机选一个元素 (index = random(0, length-1))
- Partition处理:处理array,使 pivot左侧array都比 pivot小,pivot右侧都比 pivot大
- 递归处理:对左侧array、右侧array 重复进行1、2部操作,直至左右array不可分
代码
pivot为最后元素
/* C++ implementation of QuickSort */
#include <bits/stdc++.h>
using namespace std;
// A utility function to swap two elements
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition (int arr[], int low, int high)
{
int pivot = arr[high]; // pivot
int i = (low - 1); // Index of smaller element
for (int j = low; j <= high - 1; j++)
{
// If current element is smaller than the pivot
if (arr[j] < pivot)
{
i++; // increment index of smaller element
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);
// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver Code
int main()
{
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr) / sizeof(arr[0]);
quickSort(arr, 0, n - 1);
cout << "Sorted array: \n";
printArray(arr, n);
return 0;
}
// This code is contributed by rathbh****upendra
Time Complexity (时间复杂度)
T(n) = T(k)+ T(n-k-1) + Θ(n)
- T(k) T(n-k-1)为 左右递归处理、Θ(n)为 partition处理 耗时
- k为小于pivot的元素个数
- 依赖于输入的Array,和pivot选择策略
以下分析:选取最后一个Element为Pivot
Θ(n)、 O(nLogn),代表含义不知道,我后续查查 (todo:20200118)
Worst Case
每次比较都需要swap(替换)
- 相当于array已经排过序,且和 本次排序相反,
- 例如选了个 最小数作为pivot
T(n) = T(0) + T(n-1) + Θ(n)
T(n) = T(n-1) + Θ(n)
T(n) = n^2
Best Case
不用swap(交换)
T(n) = 2T(n/2) + Θ(n)
T(n) = thea(nLogn)
Average Case
考虑所有的array排列较为困难,采取假设 O(1/9N)在左边, O(10/9N)在右边
T(n) = T(n/9) + T(9n/10) + \Θ(n)
T(n) = O(nLogn)
时间复杂度总结
- Quick Sort的Worst Case时间复杂度是n^2,多于 Merge Sort,Heap Sort。
- 但Quick Sort在实际中仍旧比 Merge Sort、Heap Sort快
- 在 真实数据(Worst Case较少出现)、大多数架构(most architectures 我推测是:硬件对 比较-替换 的加速处理)中 内部循环实现 效率较高
- Quick Sort可以通过不同的方式实现(改变pivot的位置,使Worst Case较少出现)