zoukankan      html  css  js  c++  java
  • 排序

    1. 自己的写法, 不稳定, O(n2)

        public void sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return;
            }
            for(int i = 0;i<nums.length-1;i++){
                for(int j = i+1;j<nums.length;j++){
                    if(nums[i]>nums[j]){
                        int temp = nums[i];
                        nums[i] = nums[j];
                        nums[j] = temp;
                    }
                }
            }   
        }

     2. 冒牌排序, 稳定 ,O(n2)

        public void sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return ;
            }
            for(int i = 0;i<nums.length-1;i++){
                for(int j = 0;j<nums.length-i-1;j++){
                    if(nums[j]>nums[j+1]){
                        int temp = nums[j];
                        nums[j] = nums[j+1];
                        nums[j+1] = temp;
                    }
                }
            } 
        }

    设置标记

        public void sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return ;
            }
            for(int i = 0;i<nums.length-1;i++){
                boolean flag = false;//设置标记
                for(int j = 0;j<nums.length-i-1;j++){
                    if(nums[j]>nums[j+1]){
                        int temp = nums[j];
                        nums[j] = nums[j+1];
                        nums[j+1] = temp;
                        flag = true;
                    }
                }
                if(!flag) break;//没有数据交换,提前退出
            } 
        }

     3. 简单选择排序 ,不稳定 51,52,1->1,52,51 , O(n2)

    该方法只是选择排序只有在确定了最小数的前提下才进行交换,大大减少了交换的次数。

     public void sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return ;
            }
            for(int i = 0;i<nums.length-1;i++){
                int min = i;
                for(int j = i+1;j<nums.length;j++){
                    min = nums[j]<nums[min]?j:min;                                    
                }
                if(min!=i){
                        int temp = nums[min];
                        nums[min] = nums[i];
                        nums[i] = temp;
                    }
            } 
        }

    4. 插入排序 稳定  O(n2)

        public void sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return;
            }
            for(int i = 1;i<nums.length;i++){
                int target = nums[i];
                int j = i;
                while(j>0&&nums[j-1]>target){
                    nums[j] = nums[j-1];
                    j--;
                }
                
                nums[j]=target;           
            
            } 
        }

    折半插入排序,使用二分查找优化插入排序

        public int[] sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return nums;
            }
            for(int i = 1;i<nums.length;i++){
                int target = nums[i];
                int left  = 0;
                int right =i-1;
                while(left<=right){
                    int mid =(left + right)/2;
                    if(nums[mid]<=target){
                        left = mid+1;
                    }
                    else{
                        right = mid-1;
                    }
                }
                for(int j = i;j>left;j--){
                    nums[j] = nums[j-1];
                }
                nums[left]=target;                
            } 
            return nums;
        } 

     5. 快速排序 ,不稳定 5,11,12->12,11,5,O(nlgn)

    使用分治的思想,

        public void sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return ;
            }
            quickSort(nums,0,nums.length-1);
        }
        private void quickSort(int[] nums ,int left,int right){
            if(left>=right){
                return;
            }
            int target = partition(nums,left,right);
            quickSort(nums,left,target-1);
            quickSort(nums,target+1,right);
            
        }
        private int partition(int[] nums,int left,int right){
            int target = nums[left];
            while(left<right){
                while(left<right&&nums[right]>=target){
                    right--;
                }
                nums[left]=nums[right];
                while(left<right&&nums[left]<=target){
                    left++;
                }
                nums[right] = nums[left];
            }
            nums[left]=target;
            return left;
        }

    6.堆排序,不稳定,O(nlgn)

        public int[] sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return nums;
            }
            //建立大顶堆
            for(int i=nums.length/2;i>=0;i--){
                heapAdjust(nums,i,nums.length-1);
            }
            for(int i=nums.length-1;i>0;i--){//将堆顶元素与末位交换,重新调整最大堆
                int temp = nums[0];
                nums[0]= nums[i];
                nums[i] =temp;
                heapAdjust(nums,0,i-1);
            }
            return nums;
        }
        private void heapAdjust(int[] nums ,int left,int right){
            int target = nums[left];
            for(int i = left*2+1;i<=right;i=2*i+1){
                //节点i左右孩子结点分别是2*i+1,2*i+2
                if(i<right && nums[i]<nums[i+1]){//选择出左右孩子的较大值
                    i++;
                }
                if(target >=nums[i]){
                    break;//已是大顶堆
                }
                nums[left] = nums[i];
                left= i;
            }
            nums[left] = target;
        }

     7. 希尔排序,不稳定,O(nlgn)

    插入排序的一种高效率实现

    public void sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return ;
            }
            int d = nums.length/2;
            while(d>0){
                for(int i=d;i<nums.length;i++){
                    int temp =nums[i];
                    int j = i-d;
                    while(j>=0&&nums[j]>temp){
                        nums[j+d] = nums[j];
                        j-=d;
                    }
                    nums[j+d] = temp;
                }
                d /= 2;
            }       
        } 

    8. 归并排序,稳定,空间复杂度为O(n),时间复杂度为O(nlogn)

        public int[] sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return nums;
            }
            mergeSort(nums,0,nums.length-1);
           
            return nums;
        } 
        private void mergeSort(int[] nums,int left,int right){
            if(left>=right){
                return;
            }
            int mid= (left + right)/2;//若left+right溢出 可以优化为left+(right-left)/2
            mergeSort(nums,left,mid);
            mergeSort(nums,mid+1,right);
            merge(nums,left,mid,right);
        }
        private void merge(int[] nums,int left,int mid,int right){
            int[] temp = new int[right-left+1];
            int i = left;
            int j = mid+1;
            int k = 0;
            while(i<=mid&&j<=right){
                if(nums[i]<nums[j]){
                    temp[k]= nums[i];
                    i++;
                }
                else{
                    temp[k]= nums[j];
                    j++;
                }
                k++;
            }
            while(i<=mid){
                temp[k++] = nums[i++];
            }
            while(j<=right){
                temp[k++] = nums[j++];
            }
            for(int l =0;l<temp.length;l++){
                nums[left+l] = temp[l];
            }
        }

    合并是可通过哨兵减少while循环

        private void merge(int[] nums,int left,int mid,int right){
            int[] arr1= new int[mid-left+2];//多加一个数即哨兵
            int[] arr2 = new int[right-mid+1];
            for(int i=left;i<=mid;i++){
                arr1[i-left] = nums[i];
            }
            for(int i=mid+1;i<=right;i++){
                arr2[i-mid-1] = nums[i];
            }
            int max  = nums[mid]>nums[right]?nums[mid]:nums[right];
            arr1[arr1.length-1] = max;//哨兵设为最大值,若不担心溢出可设为max+1
            arr2[arr2.length-1] = max;
            int i = 0;
            int j = 0 ;
            int k = left;
            while(k<=right){
                if(arr1[i]<=arr2[j]&&i<arr1.length-1){
                    nums[k]= arr1[i];
                    i++;
                }
                else{
                    nums[k]= arr2[j];
                    j++;
                }
                k++;
            }
        }

    9.计数排序

    public int[] sortArray(int[] nums) {
            if(null==nums||0==nums.length){
                return nums;
            }
            int min = nums[0];
            int max = nums[0];
            for(int i =1;i<nums.length;i++){
                min = min>nums[i]?nums[i]:min;
                max = max>nums[i]?max:nums[i];
            }
            int[] count = new int[max - min +1];
            Arrays.fill(count,0);
            for(int i = 0;i<nums.length;i++){
                count[nums[i]-min]++;
            }
            int k =0;
            for(int i = 0;i<count.length;i++){
                for(int j =0;j<count[i];j++){
                    nums[k++] = i+min;
                }
            }
            return nums;
        }

     10 桶排序

    计数排序是桶排序的一种特殊写法

        public int[] sortArray(int[] nums) {
            
            if(null==nums||0==nums.length){
                return nums;
            }
            int min = nums[0];
            int max = nums[0];
            for(int i =1;i<nums.length;i++){
                min = min>nums[i]?nums[i]:min;
                max = max>nums[i]?max:nums[i];
            }
            int bucketSize  = 100;//桶的大小可作为参数调整,
            int bucketCount = (max-min)/bucketSize+1;
            ArrayList<ArrayList<Integer>> bucket = new ArrayList<>(bucketCount);
            for(int i= 0;i<bucketCount;i++){
                bucket.add(new ArrayList<Integer>());
            }    
            for(int i = 0;i<nums.length;i++){
                bucket.get((nums[i]-min)/bucketSize).add(nums[i]);
            }
            int k =0;
            for(int i = 0;i<bucket.size();i++){
                //对桶排序
                if(bucket.get(i).size()>1){
                    Collections.sort(bucket.get(i));
                }
                //还原桶
                for(int j =0;j<bucket.get(i).size();j++){
                    nums[k++] = bucket.get(i).get(j);
                }
            }
            return nums;
        } 

     

  • 相关阅读:
    haproxy 基于 cookie 的会话保持
    haproxy 透明代理
    haproxy tcp keepalive
    haproxy 支持 websocket
    python 中给文件加锁
    使用python生成二维码
    python中的uuid简介
    django建表报错
    pip安装第三方包PIL失败
    python获取mac地址的方法
  • 原文地址:https://www.cnblogs.com/zhacai/p/11011961.html
Copyright © 2011-2022 走看看