1. 程式人生 > >演算法分析——快速排序

演算法分析——快速排序

快速排序

快速排序——該演算法在陣列中選擇一個稱主元的元素,將陣列分為兩部分,使得第一部分中的所有元素都小於或等於主元,而第二部分的所有元素都大於主元。對第一部分遞迴地應用快速排序演算法,然後對第二部分遞迴地應用快速排序演算法。

PS:主元的演算法選擇會影響演算法的效能。

演算法實現

package com.zss.java.algorithm;
/**
 * 快速排序
 * @author lemon
 * @date 2018/9/17 17:58
 */
public class QuickSort {
    public static void main(String[] args) {
        int[] array = {2,3,2,5,6,1,-2,3,14,12};
        quickSort(array);
        for (int i=0;i < array.length; i++){
            System.out.print(array[i] + ",");
        }
    }
    public static void quickSort(int[] list){
        quickSort(list,0,list.length-1);
    }
    //遞迴快速排序
    private static void quickSort(int[] list,int first,int last){
        if (last > first){
            int pivotIndex = partition(list,first,last); //尋找主元即劃分陣列的邊界
            quickSort(list,first,pivotIndex-1);
            quickSort(list,pivotIndex+1, last);
        }
    }
    /**
     * 選擇切分陣列的元素
     * @param list
     * @param first
     * @param last
     * @return
     */
    private static int partition(int[] list,int first,int last){
        int pivot = list[first]; //第一個元素作為主元 即依據該元素將一個數組元素劃分為兩個陣列
        int low = first + 1;
        int high = last;
        while (high > low){
            while (low <= high && list[low] <= pivot)
                low++;
            while (low <= high && list[high] > pivot)
                high--;
            //交換高於主元和低於主元的元素
            if (high > low){
                int temp = list[high];
                list[high] = list[low];
                list[low] = temp;
            }
        }
        while (high > first && list[high] >= pivot)
            high--;
        if (pivot > list[high]){
            list[first] = list[high];
            list[high] = pivot;
            return high;
        }else {
            return first;
        }
    }
}

演算法分析

最差情況下,劃分由n個元素構成的陣列需要進行n次比較和n次移動,劃分時間為O(n);最差情況下每次主元會將陣列劃分為一個大的子陣列和一個空陣列。大的子陣列的規模是在上次劃分的子陣列的規模減1,該演算法需要(n-1)+(n-2)+…+2+1 = O(n^2)時間。

最佳情況下,每次主元將陣列劃分為規模大致相等的兩部分。設T(n)表示使用快速排序演算法對包含n個元素的陣列排序所需時間,因此:

T(n) = T(n/2) + T(n/2) + n

T(n/2)表示對子陣列進行遞迴快速排序 ,n指劃分時間。

歸併排序和快速排序都使用分治法。對歸併排序,大量的工作是將兩個子線性表進行歸併,歸併是在子線性表都排好序後

進行的。對快速排序,大量的工作是將線性表劃分為兩個子線性表,劃分是在子線性表排好序前進行的。

最差情況下,歸併排序的效率高於快速排序,但平均情況下兩者效率相同。歸併排序在歸併兩個子陣列是需一個臨時陣列,而快速排序不需額外的陣列空間。因此快速排序的空間效率高於歸併排序。