排序算法——快速排序(Quick Sort)

来源:互联网 发布:情书淘宝店网址 编辑:程序博客网 时间:2024/04/28 11:55

排序算法——快速排序(Quick Sort)


算法简介(Introduction)
Quick sort is based on devide-and-conquer approach. A big problem is decided into small problems, and then solve small problem first. For example, 100 elements need to be sorted. We can divide into two 50 elements sublists. Sort both sublists separately. The idea of quick sort is the same. Firstly, a partition that arranges elements so that all elements on the left of A[s] are less than A[s] and all elements on the right of A[s] are greater than A[s] is performed.
这里写图片描述
After partition is finished, A[s] is in its final position in the sorted array. Then we do the same partition operation on the left subarray and on the right subarray separately utill the whole array is sorted.

示例(Example)
这里写图片描述

伪代码(Pseudocode)

function QuickSort(A[lo..hi])    if lo < hi then        s ⟵ Partition(lo,hi)        QuickSort(A[0..s-1])        QuickSort(A[s+1..hi])function Partition(A[lo..hi])    p ⟵ A[lo]; i ⟵ lo; j ⟵ hi    repeat        while i < hi and p ≥ A[i] then i ⟵ i + 1        while j > lo and p < A[j] then j ⟵ j - 1        swap A[i] and A[j]    until i ≥ j    swap A[i] and A[j]    swap A[lo] and A[j]

基本属性(Property)
Input: an array A[0..n-1] of n orderable elements.

Output: an array A[0..n-1] sorted in non-descending order.

In-place: yes. Only requires a constant amount O(1) of additional memory space.

Stable: no. for example, a list 5, 2, 5, 3, 4, 7, 8, 9. After first partition, the list is 4, 2, 5, 3, 5, 7, 8, 9. The relative order of A[0] and A[2] is changed.

时间复杂度(Time Complexity)
The size of inputs is n. The basic operation is key comparison “p ≥ A[i]” and “p < A[j]”. The running time of quick sort is C(n).
In the best case, that is, the pivot is the median like 5, 2, 1, 3, 4, 7, 6, 8, 9. Hence,
这里写图片描述
The two subarray has same size n/2. The amount of key comparisons performed is O(n). When the array has only one element, no swap.
By the Master Theorem, C(n) ∈ O(n log n).
In the worst case, that is, the array is already sorted like 1, 2, 3, 4, 5, 6, 7, 8, 9. After each partition, the size of problem decrement by 1. C(n) -> C(n-1) ->C(n-2) ->…-> C(3) -> C(2). Hence,
这里写图片描述
Cworst(n)=0+2+3+…+n-1+n=(n+2)(n-1)/2∈O(n^2).
In average case, that is, the elements randomly distribute in array. Let Cavg(n) be the average number of key comparisons. The pivot p can happens in any position s (n-1 ≥ s ≥ 0) after n+1 key comparisons are made to achieve partition. After this partition, the array is divided into two subarrays. The left subarray has s elements as well as the right subarray has n-s-1 elements. We assume the posibility that s goes to any position is 1/n. Then, we get the relation below:
这里写图片描述
It turns out to be O(nlogn).

Java code

public class Sort{    //Quick sort method    public static void quickSort(int[] A, int lo, int hi){        int s;        if(lo < hi){            s = partition(A, lo, hi);            quickSort(A, lo, s-1);            quickSort(A, s+1, hi);        }    }    //Partition method    public static int partition(int[] A, int lo, int hi){        int i,j,tmp,p;        p=A[lo];i=lo;j=hi;        while(i<j){            while(A[i]<=p && i<A.length)                i++;            while(A[j]>p && j>=0)                j--;            tmp=A[i];            A[i]=A[j];            A[j]=tmp;        }        tmp=A[i];        A[i]=A[j];        A[j]=tmp;        tmp=A[lo];        A[lo]=A[j];        A[j]=tmp;        return j;    }    //Test    public static void main(String[] args){        int[] A={5,2,1,3,4,7,6,8,9};        Sort.quickSort(A,0,8);        for(int i=0;i<A.length;i++)            System.out.print(A[i]+" ");    }}

运行结果(Result)

1 2 3 4 5 6 7 8 9 

写在后面的话(PS)
Quick sort can be improved with “Median-of-Three” or “Early Cut off”. I will write another article about the two improvements.

原创粉丝点击