zoukankan      html  css  js  c++  java
  • 算法回顾——快排

    今天再复习一下快排:

    当初看左神的算法课,受益匪浅。

    他是先讲解了荷兰国旗问题,然后再引出的快排,如下:

    荷兰国旗问题

    给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。

    要求时间复杂度为O(N)、额外空间复杂度为O(1)。

    分析:三个指针法:一个指向前头less,一个指向尾部more,一个是当前下标cur。当前下标由指向前面的指针推着前进。

    public static int[] partition(int[] arr, int L, int R, int num) {
            int less = L-1;   //小于
            int more = R+1;   //大于【特别注意+1】
            int cur = L;      //等于
            while (cur<more) {
                if (arr[cur]<num) {
                    swap(arr,++less,cur++);
                }else if (arr[cur]>num) {
                    swap(arr,--more,cur);//【特别注意cur】
                }else {
                    cur++;
                }
            }
            
            return arr;
        }
        
        private static void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

    快排

    根据荷兰国旗问题,变形,让num=arr[arr.length-1],即是将比较的基准值变成数组arr的末尾值;

    另外使得 R= arr.length-2; 将R变成数组 arr 中的倒数第二个值;

    这样就形成了快排;

    在这里,引入了一个“分治”的思想,以及求分治的边界点;

     

    //根据荷兰国旗问题改进
    public int[] quickSort3(int arr, int left, int right){
        if(left<right){
            int[] p = partition3(arr,left,right);//获得大小区间的临界
            quickQort3(arr,left,p[0]);//递归小区间
            quickQort3(arr,p[1],right);//递归大区间
            return arr;
        }
        
    }
    public int[] partition3(int[] arr, int L,int R){
        int left = L-1;
        int right = R;//这里和荷兰国旗不一样
        int cur = L;
        
        while(cur<right){
            if(arr[cur] < arr[R]){
                swap(arr,++left,cur++);
            }else if(arr[cur] > arr[R]){
                swap(arr,cur,--right);
            }else{
                cur++;
            }
        }
        swap(arr,R,right);//① :这里和荷兰国旗不一样:交换当前比对值到中间相等区;
        return new int[]{left+1,right};//②:这里和荷兰国旗不一样:返回小区间的右临界和大区间的左临界;
    }

    注:

    在① 处:其实是把当前的比对基准值arr[R] 和大区间的左侧边界进行交换,这样 [L, left+1)就是小区间,(right,R]就是大区间【注意区间开闭,对应  步】

    常学常乐

    Over......

  • 相关阅读:
    ue4同c#通信时的中文乱码问题
    ue4 fstring 和std::string互转
    LinqToExcel 简洁与优美开源库
    虚幻UE4的后处理特效介绍 http://www.52vr.com/thread-31215-1-1.html
    为什么你应该使用OpenGL而不是DirectX?
    会写代码是你创业路上的包袱
    (转载)怎样解决SQL Server内存不断增加问题
    UE4 Pak 相关知识总结
    淘宝运营实战操作大纲
    淘宝运营
  • 原文地址:https://www.cnblogs.com/gjmhome/p/14432646.html
Copyright © 2011-2022 走看看