zoukankan      html  css  js  c++  java
  • 递归/非递归手写快速排序+注释要点

    递归版本:

    void quicksort(int start, int end, int[] arr) {
            //必须是>= 因为当quicksort长度为2数组排列后会出现start>end,如果数组长度为1即start==end则直接返回
            if(start>=end)return;
    
            int j=end;
            int i=start;
            int base = arr[start];
    
            while (i<j) {
                //从右开始找到小于base的数index
                //必须先处理j,这样才使得j==i时,arr[i]是小于base的
                while (i<j&&arr[j]>base) {
                    j--;
                }
                //从左开始找到大于等于base的数index
                //i的这个循环处理arr[i]==base的情况,因为一开始会有arr[i]==base,不处理则base会产生位置变化,且有可能数组中有其他等于base的数
                while (i<j&&arr[i]<=base) {
                    i++;
                }
    
                swap(arr, i, j);
            }
            //这时候i==j并且保证arr[i]<=base,直接swap
            swap(arr, start, i);
            //分治递归
            quicksort(start, i - 1, arr);
            quicksort(i + 1, end, arr);
        }
    
        public void swap(int[] array, int x, int y) {
            int temp = array[x];
            array[x] = array[y];
            array[y] = temp;
        }
    

    非递归版本:

    ...省略swap
    
    //我们只需要对这个方法稍作改造,返回base的index,取消最前面的判断(放到了外层sort方法)
        int quicksort(int start, int end, int[] arr) {
    
            int j = end;
            int i = start;
            int base = arr[start];
    
            while (i < j) {
                //从右开始找到小于base的数index
                //必须先处理j,这样才使得j==i时,arr[i]是小于base的
                while (i < j && arr[j] > base) {
                    j--;
                }
                //从左开始找到大于等于base的数index
                //i的这个循环处理arr[i]==base的情况,因为一开始会有arr[i]==base,不处理则base会产生位置变化,且有可能数组中有其他等于base的数
                while (i < j && arr[i] <= base) {
                    i++;
                }
    
                swap(arr, i, j);
            }
            //这时候i==j并且保证arr[i]<=base,直接swap
            swap(arr, start, i);
    
            return i;
        }
    
    
     void sort(int[] arr) {
            //本质就是递归左右坐标改成用队列存储左右坐标再一次次调用,用stack也是同理
            Queue<Integer> queue = new LinkedBlockingQueue();
            //初始传入整个数组
            queue.add(0);
            queue.add(arr.length - 1);
            int l = 0, r = 0, m = 0;
            while (!queue.isEmpty()) {
                //先进先出,获取要排列的数组的左右坐标
                l = queue.poll();
                r = queue.poll();
                m = quicksort(l, r, arr);
                //保证传入的子数组长度起码为2,否则就不用排了
                if (m - 1 > l) {
                    queue.add(l);
                    queue.add(m - 1);
                }
                if (m + 1 < r) {
                    queue.add(m + 1);
                    queue.add(r);
                }
            }
    
        }
    
  • 相关阅读:
    2020.08.28【周报】
    区间合并【排序、栈】
    1042 数字0-9的数量【解题数分DP】
    asp.net数据分页方法
    纯css面板插件,自适应,多样式
    c#winform图表控件使用示例
    使用妹子UI开发的体验分享
    阿里云储存代码整理(由三卷天书整理)
    测试程序的时候用到写参数或者错误日志的几个方法,用来方便发现错误
    fineUI表格控件各属性说明
  • 原文地址:https://www.cnblogs.com/CodeSpike/p/13600845.html
Copyright © 2011-2022 走看看