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......

  • 相关阅读:
    java学习笔记——基于Robot类的屏幕分享
    Java实例——基于jsoup的简单爬虫实现(从智联获取工作信息)
    Java实例练习——基于UDP协议的多客户端通信
    java实例练习——基于TCP/IP协议的多客户端通信
    我个人的Java学习经验(一家之言)
    PHP mac localhost 环境下发送邮件
    php ob_start()、ob_end_flush和ob_end_clean()多级缓冲
    php ob_start()、ob_end_flush和ob_end_clean()多级缓冲
    程序员应该知道的13个设计技巧
    程序员应该知道的13个设计技巧
  • 原文地址:https://www.cnblogs.com/gjmhome/p/14432646.html
Copyright © 2011-2022 走看看