排序-2

快速排序

和归并有些类似,处理上归并是中间分隔处理,快排是找一个random值进行当作基准,然后再两边分开处理,再用递归分治的思路。

从12345-> 123,4,5-> 1,2,3, 4, 5

 

截取自《算法》 

 

抽象实现

    private static void sort(int[] a) {
        StdRandom.shuffle(e);
        sort();
    }
    private static void sort(int[] a, int lo, int hi) {
        if (hi <= lo) {
            break;
        }
        int j = partition(a, lo, hi);
        sort(a, lo, j - 1);
        sort(a, j + 1, hi);
    }
    private static int partition(int[] a, int lo, int hi) {
        int i = lo;
        int j = hi;
        int v = a[lo];
        while (true) {
            while (less(a[++i], v)) {
                if (i == hi) {
                    break;
                }
            }
            while (less(v, a[--j])) {
                if (j == lo) {
                    break;
                }
            }
            if (i >= j) {
                break;
            }
            exch(a, i, j);
        }
        exch(a, lo, j);
        return j;
    }

1.要原地切分,因为如果自设一个辅助数组,会发生频繁的复制,开销很大。

2.注意越界问题,尤其是切分的基准元素是最大或者最小。

3.保持随机性,这种情况在大数据下验证有明确的性能提升。

4.注意循环的终止。

5.处理与切分元素重复的元素,避免等值元素的交换,这是一种重复元素较少的处理。

6.递归的终止条件。

 

范例实现

public class QuicklySort {
    public static void quickSort(int[] s, int l, int r) {
        if (l < r) {
            int i = l;
            int j = r;
            int x = s[l];

            while (i < j) {
                while (i < j && s[j] > x) {
                    j--;
                }
                if (i < j) {
                    s[i] = s[j];
                    i++;
                }

                while (i < j && s[i] < x) {
                    i++;
                }
                if (i < j) {
                    s[j] = s[i];
                    j--;
                }
            }
            s[i] = x;
            quickSort(s, l, i);
            quickSort(s, i + 1, r);
        }

    }

 

三向切分快排

 

 

 

 

 

抽象实现

 private static void sort3way(int[] a, int lo, int hi) {
        if (hi <= lo) {
            return;
        }
        int lt = lo;
        int i = lo + 1;
        int gt = hi;
        int v = a[lo];
        while (i <= gt) {
            int comp = a[i].compareTo(v);
            if (comp < 0) {
                exch(a, lt++, i++);
            } else if (comp > 0) {
                exch(a, i, gt--);
            } else {
                i++;
            }
        }
        sort(a, lo, lt - 1);
        sort(a, gt + 1, hi);
    }

这算是一种快排的优化,避免了大量重复元素的交换。

posted @ 2019-12-12 16:25  zhangyu63  阅读(92)  评论(0编辑  收藏  举报