1. 程式人生 > >快速排序(Quick Sort)

快速排序(Quick Sort)

sin aik tex 狀態 整體 splay 好的 優化 return

基本思想:

  通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分的關鍵字小,則可分別對著兩部分記錄進行排序,以達到整體有序的目的。

通俗點說就是:

  在待排記錄中找出一個記錄,然後想辦法將它放到一個位置,是得它左邊的值都比他小,右邊的值都比他大(正序或者倒序),把這個記錄稱作樞軸(pivot)。

然後對樞軸左邊和右邊的記錄重復這個步驟,直到達到整體有序的狀態。

  可以先看一下快排的百度介紹

快排介紹:

優化後的快排(只有更好的沒有最好的,這個也是一樣。)

技術分享圖片
package algorithm;

import java.util.Arrays;

/**
* @author wzy * @since 18-6-20 */ public class QuickSort { public static void quickSort(int a[], int low, int high) { if (low > high) return; int pivot; //在這裏使用了尾遞歸優化,采用叠代的方法縮減虛擬機棧的深度,從而提高整體性能。 //虛擬機棧中存放的東西請自行搜索 while (low < high) { pivot
= partition(a, low, high); quickSort(a,low,pivot-1); low = pivot + 1; } } /** * @param a 待排數組 * @param low 待排數組起始下標 * @param high 待排數組截止下標 * @return pivot的下標 */ private static int partition(int[] a, int low, int high) { int
pivot = getPivot(a); while (low < high) { while (low < high && a[high]>=index) high--; if (low < high) a[low++] = a[high]; while (low < high && a[low] < index) low++; if (low < high) a[high--] = a[low]; } a[low] = index; return low; } /** * 由於pivot的選擇直接會影響到排序的性能(遞歸調用的次數)。 * 所以我們如果選擇的pivot越接近中間值,效果越好。 * 在這裏使用“三數取中”的方法來獲取pivot * * @param a 待排數組 * @return pivot */ private static int getPivot(int[] a) { //省略參數檢查 int h, m; m = (h = a.length - 1) >> 1; return a[0] >= a[m] && a[0] <= a[h] ? a[0] : (a[m] >= a[0] && a[m] <= a[h] ? a[m] : a[h]); } public static void main(String[] args) { int a[] = {49, 38, 65, 97, 76, 13, 27, 49, 1, 4, 2, 5, 7, 99, 88, 77, 66}; quickSort(a, 0, a.length - 1); System.out.println(Arrays.toString(a)); } }
QuickSort

  快速排序也好,其他排序也好,我現在還沒了解到有十全十美的排序算法。不同的排序算法都會有自己的優點和缺點,所以我們要針對不同的情況去選擇合適的算法。

快速排序的復雜度和穩定性:

  平均情況:O(nlogn)

  最好情況:O(nlogn)

  最壞情況:O(n2)

  輔助空間:O(logn)~O(n)

  穩定性:不穩定

快速排序(Quick Sort)