java中的常见排序示例代码(含优化方案和拓展方法)

 更新时间:2026年01月07日 10:02:21   作者:YOU OU  
在Java中常见的排序算法包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序和堆排序等,这篇文章主要介绍了java中常见排序(含优化方案和拓展方法)的相关资料,需要的朋友可以参考下

常见的排序方法有以下7种,会一一讲解,外加拓展的计数排序

一. 直接插入排序

 public static void insetSort(int[] array){
        for(int i=1;i<array.length;i++){
            int j=i -1;
            int tmp=array[i];
            for(;j>=0;j--){
                if(array[j]>tmp){
                    array[j+1]=array[j];
                }else{
                    array[j+1]=tmp;
                    break;
                }
            }
            array[j+1]= tmp;

        }
    }

时间复杂度:O(N^2)

最坏情况下(逆序) 5 4 3 2 1

最好情况下(本身是有序的)O(N)

                    如果数据越有序,直接插入排序越快

空间复杂度:O(1)

稳定性:稳定的排序

 本身如果是一个稳定的排序,可以实现为不稳定的
但是 如果一个排序 本身就是不稳定,不能实现为稳定的排序

二. 希尔排序

public static void shellSort(int[]array){
        int gap=array.length;
        while(gap>1){
            gap=gap/2;
            shell(array,gap);
        }
    }

    private static void shell(int[] array, int gap) {
        for(int i=gap;i<array.length;i++){
            int j=i -gap;
            int tmp=array[i];
            for(;j>=0;j-=gap){
                if(array[j]>tmp){
                    array[j+gap]=array[j];
                    array[j]=tmp;
                }else{
                    array[j+gap]=tmp;
                    break;
                }
            }
            array[j+gap]= tmp;
        }
    }

时间复杂度: O(N^1.3~N^1.5)

空间复杂度:O(1)

稳定性:不稳定

三. 选择排序

 private static void swap(int[] array,int i,int j){
        int tmp=array[i];
        array[i]=array[j];
        array[j]=tmp;
    }

方法一

public static void selectSort(int[] array){
        int left=0;
        int right=array.length-1;
        while(left<right){
            int minIndex=left;
            int maxIndex=left;
            for (int i = left+1; i <=right; i++) {
                if(array[i]<array[minIndex]){
                    minIndex=i;
                }
                if(array[i]>array[maxIndex]){
                    maxIndex=i;
                }
            }
            swap(array,left,minIndex);
            if(maxIndex==0){
               maxIndex=minIndex;
            }
            swap(array,right,maxIndex);
            left++;
            right--;
        }
    }

方法二

 public static void selectSort1(int[] array){
        for (int i = 0; i < array.length; i++) {
            int minIndex=i;
            for (int j = i+1; j < array.length; j++) {
                if(array[j]<array[minIndex]){
                    minIndex=j;
                }
            }
            swap(array,i,minIndex);
        }
    }

时间复杂度:O(N^2)

                         和数据是否与有序无关

空间复杂度:O(1)

稳定性:不稳定

四. 堆排序

private static void swap(int[] array,int i,int j){
        int tmp=array[i];
        array[i]=array[j];
        array[j]=tmp;
    }
public static void heapsort(int[] array){
        createHeap(array);
        int end= array.length-1;
        while(end>0){
            swap(array,0,end);
            siftDown(array,0,end);
            end--;
        }
    }

    private static void createHeap(int[] array){
        for (int parent = (array.length-1-1)/2; parent>=0; parent--) {
            siftDown(array,parent,array.length);
        }
    }

    private static void siftDown(int[] array, int parent, int end) {
        int child=parent*2+1;
        while(child<end){
            if(child+1<end && array[child]<array[child+1]){
                child++;
            }
            if(array[child]>array[parent]){
                swap(array,parent,child);
                parent=child;
                child=parent*2+1;
            }else{
                break;
            }
        }
    }

时间复杂度:O(n*logN)

空间复杂度:O(1)

稳定性:不稳定

五. 冒泡排序

加入flg的判断是为了优化此排序

    public static void bubbleSort(int[]array){
        for (int i = 0; i < array.length-1; i++) {
            boolean flg=false;
            for (int j = 0; j < array.length-1-i; j++) {
                if(array[j]>array[j+1]){
                    swap(array,j,j+1);
                    flg=true;
                }
            }
            if(!flg){
                break;
            }
        }
    }

时间复杂度:O(N^2)

注意:冒泡排序优化前的时间复杂度为O(),优化后可以达到O(N)

空间复杂度:O(1)

稳定性:稳定

六. 快速排序(已优化)

insertSortRange()  getMiddleNum()  是为了优化快速排序

 private static void swap(int[] nums,int i,int j){
        int tmp=nums[i];
        nums[i]=nums[j];
        nums[j]=tmp;
    }
   public static void quickSort(int[] array) {
        //quick(array,0,array.length-1);
        quickNor(array,0,array.length-1);
    }
private static void quick(int[] array,int start,int end){
        if(start>=end){
            return;
        }

        if(end-start+1<=10){
            insertSortRange(array,start,end);
            return ;
        }
        int midIndex=getMiddleNum(array,start,end);
        swap(array,start,midIndex);
        int pivot=partition(array,start,end);
        quick(array,start,pivot-1);
        quick(array,pivot+1,end);
    }
 private static void insertSortRange(int[] array,int start,int end){
        for(int i=start+1;i<=end;i++){
            int j=i -1;
            int tmp=array[i];
            for(;j>=0;j--){
                if(array[j]>tmp){
                    array[j+1]=array[j];
                }else{
                    array[j+1]=tmp;
                    break;
                }
            }
            array[j+1]= tmp;
        }
    }
 private static int getMiddleNum(int[] array,int left,int right){
        int mid=(left+right)/2;
        if(array[left]<array[right]){
            if(array[left]>array[mid]){
                return left;
            }else if(array[right]<array[mid]){
                return right;
            }else{
                return mid;
            }
        }else{
            if(array[right]>array[mid]){
                return right;
            }else if(array[left]<array[mid]){
                return right;
            }else{
                return mid;
            }
        }
    }
  private static int partition2(int[] array, int left, int right){
        int tmp=array[left]; //挖坑法
        while(left<right){
            while(left<right && array[right]>=tmp){
                right--;
            }
            array[left]=array[right];
            while(left<right && array[left]<=tmp){
                left++;
            }
            array[right]=array[left];
        }
        array[left]=tmp;
        return left;
    }

时间复杂度:O(N*logN)

 最坏情况下: 当数据给的是1 2 3 4 5 6 7 ……

                                             9 8 7 6 5 4 1 …… 

                       有序的情况下:O(N^2)

最好的情况下:O(N*logN)

注意:一般情况下,说快速排序的时间复杂度默认为 O(N*logN) 优化过后  

空间复杂度:O(logN)

最坏情况下:O(N)

最好情况下:O(logN)

稳定性:不稳定

拓展:

1.partition的实现方法

一共有三种实现方法:挖坑法(推荐)

                                    Hoare版 

                                    前后指针法

  //挖坑法
private static int partition2(int[] array, int left, int right){
        int tmp=array[left]; //挖坑法
        while(left<right){
            while(left<right && array[right]>=tmp){
                right--;
            }
            array[left]=array[right];
            while(left<right && array[left]<=tmp){
                left++;
            }
            array[right]=array[left];
        }
        array[left]=tmp;
        return left;
    }
 //hoare版
private static int partitionHoare(int[] array, int left, int right){
        int tmp=array[left];
        int tmpLeft=left;
        while(left<right){
            while(left<right && array[right]>=tmp){
                right--;
            }
            while(left<right && array[left]<=tmp){
                left++;
            }
            swap(array,left,right);
        }
        swap(array,left,tmpLeft);
        return left;
    }
 //前后指针法
private static int partition(int[] array, int left, int right){
        int cur=left+1;
        int prev=left;
        while(cur<=right){
            if(array[cur]<array[left] && array[++prev]!=array[cur]){
                swap(array,cur,prev);
            }
            cur++;
        }
        swap(array,prev,left);
        return prev;
    }

2.非递归quick实现方法

public static void quickNor(int[] array,int start,int end){
        Deque<Integer> stack =new ArrayDeque<>();
        int pivot=partition(array,start,end);
        if(pivot>start+1){
            stack.push(start);
            stack.push(pivot-1);
        }
        if(pivot<end-1){
            stack.push(pivot+1);
            stack.push(end);
        }
        while(!stack.isEmpty()){
            end=stack.pop();
            start=stack.pop();
            pivot=partition(array,start,end);
            if(pivot>start+1){
                stack.push(start);
                stack.push(pivot-1);
            }
            if(pivot<end-1){
                stack.push(pivot+1);
                stack.push(end);
            }
        }
    }

七. 归并排序

 public static void mergesort(int[] array){
       mergeSortTmp(array,0,array.length-1);
    }
  private static void mergeSortTmp(int[] array,int left,int right){
        if(left>=right){
            return;
        }
        int mid=(left+right)/2;
        mergeSortTmp(array,left,mid);
        mergeSortTmp(array,mid+1,right);

        merge(array,left,mid,right);
    }
    private static void merge(int[] array, int left, int mid, int right){
        int[] tmp=new int[[right-left+1];
        int k=0;
        int s1=left;
        int s2=mid+1;
        while(s1<=mid && s2<=right){
            if(array[s1]<array[s2]){
                tmp[k++]=array[s1++];
            }else{
                tmp[k++]=array[s2++];
            }
        }
        while(s1<=mid){
            tmp[k++]=array[s1++];
        }
        while(s2<=right){
            tmp[k++]=array[s2++];
        }
        for (int i = 0; i < k; i++) {
            array[i+left]=tmp[i];
        }
    }

时间复杂度:O(N*logN)

空间复杂度:O(N)

稳定性:稳定

拓展:非递归实现

public static void mergeSortNor(int[] array){
        int gap=1;
        while(gap<array.length){
            for (int i = 0; i < array.length; i=i+gap*2) {
                int left=i;
                int mid=left+gap-1;
                if(mid>=array.length){
                    mid=array.length-1;
                }
                int right=mid+gap;
                if(right>=array.length){
                    right=array.length-1;
                }
                merge(array,left,mid,right);
            }
            gap*=2;
        }
    }

八. 计数排序(非基于比较排序)

 public static void countSort(int[] array){
        int maxVal=array[0];
        int minVal=array[0];
        for (int i = 0; i < array.length; i++) {
            if(minVal>array[i]){
                minVal=array[i];
            }
            if(maxVal<array[i]){
                maxVal=array[i];
            }
        }
        int len=maxVal-minVal+1;
        int[] count=new int[len];
        for (int i = 0; i < array.length; i++) {
            int index=array[i];
            count[index-minVal]++;
        }
        int index=0;
        for (int i = 0; i < count.length; i++) {
            while(count[i]!=0){
                array[index]=i+minVal;
                index++;
                count[i]--;
            }
        }
    }

适用范围:数据集中在一定的范围内

如:0~9   89~99 等

时间复杂度:O(范围+N)

                              范围越大  越慢

空间复杂度:O(范围)

稳定性:稳定

总结:

稳定的排序:

冒泡排序、插入排序、归并排序

表格对比:

到此这篇关于java中常见排序的文章就介绍到这了,更多相关java常见排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

最新评论