1. 程式人生 > >快速排序 Java 針對重複元素

快速排序 Java 針對重複元素

與歸併排序一樣,快速排序也是採用分治策略。但是歸併排序的計算量主要集中在有序子序列的合併上,而子序列的劃分幾乎不花費時間。快速排序恰恰相反,可以在o(1)的時間內完成子序列的合併,對於將原問題劃分上需要花費O(n)的時間。對於子序列的劃分上,可能的劃分是極不平等的,因此該演算法不能保證最壞情況下的O(nlogn)的時間複雜度。一般來說,快排是首選的演算法。

因此:版本一

package Basic.QuickSort;
import java.util.Random;
/**
 * 該方法對於出現大量的重複元素的時候,軸點位置總是接近與lo,子序列的劃分極不均勻,二分遞迴退化為線性遞迴,遞迴深度接近於O(n),執行時間接近於O(n2)
 * 在移動lo和hi時,同時比較相鄰元素的:lo與hi會交替移動,二者移動的距離大致相等。見於第二版本,而對於重複元素不多的時候,法二反而會增加計算量。
 */
public class QuickSort_v1 { public static void main(String[] args) { int[] array = {9, 10, 5, 84, 2, 45, 1, 4, 56, 1}; quickSort(array, 0, array.length - 1); for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } } public static
void quickSort(int[] array, int lo, int hi) { if (lo >= hi) return; int mid = partition(array, lo, hi); quickSort(array, lo, mid - 1); quickSort(array, mid + 1, hi); } private static int partition(int[] array, int lo, int hi) { swap(array, lo, hi); int
key = array[lo]; while (lo < hi) { while (lo < hi && array[hi] >= key) hi--; array[lo] = array[hi]; while (lo < hi && array[lo] <= key) lo++; array[hi] = array[lo]; } array[hi] = key; return hi; } private static void swap(int[] array, int lo, int hi) { int temp = 0; Random r = new Random(); int k = r.nextInt(10) % (hi - lo + 1) + lo; temp = array[lo]; array[lo] = array[k]; array[k] = temp; } }

版本二:
該方法對於出現大量的重複元素的時候,軸點位置總是接近與lo,子序列的劃分極不均勻,二分遞迴退化為線性遞迴,遞迴深度接近於O(n),執行時間接近於O(n2)在移動lo和hi時,同時比較相鄰元素的:lo與hi會交替移動,二者移動的距離大致相等。見於第二版本,而對於重複元素不多的時候,法二反而會增加計算量。

package Basic.QuickSort;


import java.util.Random;

import static Basic.QuickSort.QuickSort_v1.quickSort;

/**
 * 
 */
public class QuickSort_v2 {
    public static void main(String[] args) {
        int[] array = {9, 10, 5, 84,56 ,96,2, 45, 1, 4, 56,1,10000};
        quickSort2(array, 0, array.length - 1);
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }

    public static void quickSort2(int[] array, int lo, int hi) {
        if (lo >= hi) return;
        int mid = partition(array, lo, hi);
        quickSort(array, lo, mid - 1);
        quickSort(array, mid + 1, hi);
    }

    private static int partition(int[] array, int lo, int hi) {
        swap(array, lo, hi);
        int key = array[lo];
        while (lo < hi) {
            while (lo < hi) {
                if (key < array[hi]) hi--;
                else {
                    array[lo++] = array[hi];
                    break;
                }
            }
            while (lo < hi) {
                if (array[lo] < key) lo++;
                else {
                    array[hi--] = array[lo];
                    break;
                }
            }
        }
        array[lo] = key;
        return lo;
    }
    private static void swap(int[] array, int lo, int hi) {
        int temp = 0;
        Random r = new Random();
        int k = r.nextInt(10) % (hi - lo + 1) + lo;
        temp = array[lo];
        array[lo] = array[k];
        array[k] = temp;

    }
}