• 【排序】三种经典高效排序算法


    (一)快速排序

    第一步:选择轴值,选择策略

    第二步:将待排序序列划分为两个子序列L和R,使得L中的所有记录都小于等于轴值,而R中的所有记录都大于轴值,也就是关键的划分算法。

    第三步:对子序列L和R递归快速排序。

    class Solution {
        //快速排序
        public int[] sortArray(int[] nums) {
            if(nums==null ||nums.length<2)
                return nums;
            quickSort(nums,0,nums.length-1);
            return nums;
        }
        public void quickSort(int[] nums,int low,int high){
            if(low>=high)
                return;
            int index=partition(nums,low,high);
            quickSort(nums,low,index-1);
            quickSort(nums,index+1,high);
        }
        public int partition(int[] nums,int low,int high){
            int i=low,j=high;
            int temp=nums[low];  //轴值选择最左边的一个
            while(i<j){
                while(i<j && nums[j]>=temp)
                    j--;
                if(i<j){
                    nums[i]=nums[j];
                    i++;
                }
                while(i<j && nums[i]<temp)
                    i++;
                if(i<j){
                    nums[j]=nums[i];
                    j--;
                }
            }
            nums[i]=temp;
            return i;
        }
    }
    

    (二)归并排序

    二路归并:

    class Solution {
        //归并排序
        public int[] sortArray(int[] nums) {
            if(nums==null && nums.length<2)
                return nums;
            mergeSort(nums,0,nums.length-1);
            return nums;
        }
        public void mergeSort(int[] nums,int low,int high){
            if(low>=high)
                return ;
            int mid=low+(high-low)/2;
            mergeSort(nums,low,mid);
            mergeSort(nums,mid+1,high);
            merge(nums,low,mid,high);
        }
        public void merge(int[] nums, int low,int mid,int high){
            int[] temp=new int[high-low+1];
            int i=low,j=mid+1,k=0;
            while(i<=mid && j<=high){
                if(nums[i]<=nums[j])
                    temp[k++]=nums[i++];
                else
                    temp[k++]=nums[j++];
            }
            while(i<=mid)
                temp[k++]=nums[i++];
            while(j<=high)
                temp[k++]=nums[j++];
            
            for(int t=0;t<temp.length;t++)
                nums[t+low]=temp[t];
        }
    }
    

    (三)堆排序

    堆:

      一个关键字序列{K0,K1,…,Kn-1},当满足条件(1)或(2)时就称为堆。

    (1) Ki ≤K2i +1 或 (2) Ki ≥K2i+1

    ​ Ki ≤K2i+2      Ki ≥K2i+2

      满足(1)的序列为最小堆(小顶堆)。

      满足(2)的序列为最大堆(大顶堆)。

    筛选法:

    堆排序:

    class Solution {
        //堆排序,O(nlogn)
        public int[] sortArray(int[] nums) {
            buildHeap(nums);  //建立初始堆
            for(int i=nums.length-1;i>=0;i--){
                //交换
                int temp=nums[0];
                nums[0]=nums[i];
                nums[i]=temp;
    
                //重新构建大顶堆,0下筛
                heapAdjustDown(nums,i,0);
            }
    
            return nums;
        }
    
        public void buildHeap(int[] nums){  //建堆
            for(int i=nums.length/2-1;i>=0;i--)
                heapAdjustDown(nums,nums.length,i);
        }
    	
        //下筛算法,时间复杂度O(nlogn)
        public void heapAdjustDown(int[] nums, int n, int h){  //筛选算法,下筛,将nums[h]拉下来
            int i=h,temp=nums[h];  //标记父结点
            int j=2*i+1; //左孩子
    
            while(j<n){
                if(j<n-1 && nums[j+1]>nums[j])
                    j=j+1;  //j为孩子中的较大者
                
                if(temp>nums[j])  //满足大顶堆
                    break;
                else{
                    nums[i]=nums[j];
                    i=j;
                    j=2*i+1;
                }
            }
            nums[i]=temp;
        }
    }
    
  • 相关阅读:
    时间复杂度
    随机数生成
    promise封装异步函数
    谷歌浏览器占用cpu过高,如何解决?
    大二层网络
    kubernetes 二进制安装部署手册
    SeaWeedfs 分布式网络文件存储介绍
    seaweedfs基本使用
    SeaweedFS基本介绍
    Linux下shell通用脚本启动jar(微服务)
  • 原文地址:https://www.cnblogs.com/gzshan/p/12760434.html
Copyright © 2020-2023  润新知