• 排序-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);
        }

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

    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    六大设计原则(一)
    .Net MVC 实现WebSocket
    Socket基础三
    Linux date命令的用法(转)
    SpringBoot自定义校验注解校验日期时间格式字符串
    前缀、中缀、后缀表达式
    什么是重放攻击,列举几种常见防御手段?
    09月13日总结
    09月12日总结
    09月11日总结
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12029955.html
Copyright © 2020-2023  润新知