演算法分析——快速排序
阿新 • • 發佈:2019-02-02
快速排序
快速排序——該演算法在陣列中選擇一個稱主元的元素,將陣列分為兩部分,使得第一部分中的所有元素都小於或等於主元,而第二部分的所有元素都大於主元。對第一部分遞迴地應用快速排序演算法,然後對第二部分遞迴地應用快速排序演算法。
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指劃分時間。
歸併排序和快速排序都使用分治法。對歸併排序,大量的工作是將兩個子線性表進行歸併,歸併是在子線性表都排好序後
最差情況下,歸併排序的效率高於快速排序,但平均情況下兩者效率相同。歸併排序在歸併兩個子陣列是需一個臨時陣列,而快速排序不需額外的陣列空間。因此快速排序的空間效率高於歸併排序。