1. 程式人生 > >快速排序和歸併排序

快速排序和歸併排序

分而治之(divide - conquer);每個遞迴過程涉及三個步驟
第一, 分解: 把待排序的 n 個元素的序列分解成兩個子序列, 每個子序列包括 n/2 個元素.
第二, 治理: 對每個子序列分別呼叫歸併排序MergeSort, 進行遞迴操作
第三, 合併: 合併兩個排好序的子序列,生成排序結果.

/**
* 分治演算法思路: 將一個大問題,分解成同樣的多個小問題,解決每個小問題,最後合併就解決了大問題。
* @param arr
* @param low
* @param high
*/
    public static void mergeSort(int arr[], int low, int
high) { int midle = (low + high) >>> 1; if (low < high) { // 控制至少兩個才能分解合併 // 分解 mergeSort(arr, low, midle); mergeSort(arr, midle + 1, high); //合併 merge(arr, low, midle, high); } } // 合併 public
static void merge(int arr[], int low, int midle, int high) { int center = midle + 1; // 右邊陣列的起始位置 int temp[] = new int[high - low + 1]; // 臨時陣列 int index = 0; while (low <= midle && center <= high) { if
(arr[low] < arr[center]) { temp[index++] = arr[low++]; } else if (arr[low] > arr[center]) { temp[index++] = arr[center++]; } else { temp[index++] = arr[low++]; temp[index++] = arr[center++]; } } while (low <= midle) { // 左邊還有剩餘 temp[index++] = arr[low++]; } while (center <= high) { // 右邊還有剩餘 temp[index++] = arr[center++]; } copy(arr, temp, high); // 拷貝元素 } public static void copy(int arr[], int temp[], int high) { for (int i = temp.length - 1; i >= 0; i--) { arr[high--] = temp[i]; } }

快速排序是氣泡排序的改進版,也是最好的一種內排序,在很多面試題中都會出現,也是作為程式設計師必須掌握的一種排序方法。
思想:1.在待排序的元素任取一個元素作為基準(通常選第一個元素,但最的選擇方法是從待排序元素中隨機選取一個作為基準),稱為基準元素;
2.將待排序的元素進行分割槽,比基準元素大的元素放在它的右邊,比其小的放在它的左邊;
3.對左右兩個分割槽重複以上步驟直到所有元素都是有序的。
所以我是把快速排序聯想成東拆西補或西拆東補,一邊拆一邊補,直到所有元素達到有序狀態。

/**
*
* void QuickSort(SeqList R,int low,int high) {
        int pivotpos; //劃分後的基準記錄的位置
        if(low<high){ //僅當區間長度大於1時才須排序
            pivotpos=Partition(R,low,high); //對R[low..high]做劃分
            QuickSort(R,low,pivotpos-1); //對左區間遞迴排序
            QuickSort(R,pivotpos+1,high); //對右區間遞迴排序
        }
  }
*/
    public static void quickSort(int low, int high, int arr[]) {
        int position;
        if (low < high) {
            position = partition(arr, low, high);
            quickSort(low, position-1, arr);
            quickSort(position+1, high, arr);
        }
  }

   private static int partition(int arr[], int low, int high) {
        int res = arr[low];
        while (low != high) {
            while (low < high && arr[high] >= res) {
                high--;
            }
            arr[low] = arr[high];

            while (low < high && arr[low] <= res) {
                low++;
            }
            arr[high] = arr[low];
        }
        arr[low] = res; // 基數歸位
        return low;
}