Java中常见的七大排序总结

一、直接插入排序
原理:整个区间被分为:有序区间和无序区间;每次选择无序区间的第一个元素,在有序区间内选择合适的位置插入。

当待排序区间元素比较少或者接近有序时,直接插入的效率比较高。

private static void insertSort(int[] array){
       for(int bound=1;bound<array.length;bound++){
           int temp=array[bound];
           int cur=bound-1;
           for(;cur>=0;cur--){
               if(array[cur]>temp){
                   array[cur+1]=array[cur];
               }
               else{
                   break;
               }
           }
           array[cur+1]=temp;
       }
    }

时间复杂度:最好:数据有序O(n);最坏:数据逆序O(n^2);平均 O(n^2)。
空间复杂度:O(1)
稳定性:稳定排序。

二、希尔排序
原理:将待排序区间分成若干子区间,分别进行直接插入排序。经过上述粗略调整,整个序列中的记录基本有序,最后一次再对全部记录进行直接插入排序。
  private static void shellSort(int[] array){
        int gap=array.length/2;
        while(gap>1){
            shellSortHelper(array,gap);
            gap/=2;
        }
        shellSortHelper(array,1);
    }
    private static void shellSortHelper(int[] array,int gap){
        for(int bound=gap;bound<array.length;bound++){
            int temp=array[bound];
            int cur=bound-gap;
            for(;cur>=0;cur-=gap){
                if(array[cur]>temp){
                    array[cur+gap]=array[cur];
                }
                else{
                   break;
                }
            }
            array[cur+gap]=temp;
        }
    }

时间复杂度:O(n^1.3)
空间复杂度:O(1)
稳定性:不稳定排序

三、冒泡排序
原理:反复扫描待排序记录序列,依次比较相邻两个元素的大小,若是逆序就交换位置。
  private static void bubbleSort(int[] array){
        for(int i=0;i<array.length;i++){
            for(int j=0;j<array.length-i-1;j++){
                //如果这里写成>=就无法保证稳定性
                if(array[j]>array[j+1]){
                    int temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                }else{
                    continue;
                }
            }
        }
    }

时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:稳定排序

四、快速排序
原理:取一个基准值K,将左侧区间整理成小于等于基准值,右侧区间整理成大于等于基准值。

取最后一个元素为基准值,从左往右找,找到一个大于基准值的元素;从右往左找,找到一个小于基准值的元素,交换两个元素;重复刚才的过程,直到左右下标重合。重合后,交换基准值和重合位置元素。

private static void quickSort(int[] array,int beg,int end){
        if(beg>=end){
            return;
        }
        int index=partition(array,beg,end);
        quickSort(array,beg,index-1);
        quickSort(array,index+1,end);
    }

    private static int partition(int[] array,int beg,int end){
        int left=beg;
        int right=end;
        int temp=array[end];
        while(left<right){
            while(left<right&&array[left]<=temp){
                left++;
            }
            while(left<right&&array[right]>=temp){
                right--;
            }
           swap(array,left,right);
        }
        swap(array,left,end);
        return left;
    }

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

时间复杂度:最坏情况数组逆序O(N^2),平均O(NlogN)
空间复杂度:最坏情况数组逆序O(N),平均O(NlogN)
稳定性:不稳定排序

五、简单选择排序

原理:从待排序区间中选出最小值,放到已排序区间末尾。通过打擂台方式找到最小值。
 private static void selectSort(int[] array){
        for(int bound=0;bound<array.length;bound++){
            for(int cur=bound+1;cur<array.length;cur++){
                if(array[cur]<array[bound]){
                    int temp=array[bound];
                    array[bound]=array[cur];
                    array[cur]=temp;
                }
            }
        }
    }

时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:不稳定排序

六、堆排序
原理:从待排序区间找到一个做大值,放到已排序区间最前面。
private static void heapSort(int[] array){
        createHeap(array);
        for(int i=0;i<array.length;i++){
            swap(array,0,array.length-i-1);
            shiftDown(array,array.length-i-1,0);
        }
    }

    private static void createHeap(int[] array) {
        for(int i=(array.length-1-1)/2;i>=0;i--){
            shiftDown(array,array.length,i);
        }
    }
    private static void shiftDown(int[] array,int size,int index){
        //建大堆
       int parent=index;
       int child=2*parent+1;
       while(child<size){
           if (child + 1 < size && array[child+1]>array[child]) {
               child=child+1;
           }
           if(array[parent]<array[child]){
               swap(array,child,parent);
           }
           else{
               break;
           }
           parent=child;
           child=2*parent+1;
       }
    }
    private static void swap(int[] array,int i, int j) {
        int m=array[i];
        array[i]=array[j];
        array[j]=m;
    }

时间复杂度:O(NlogN)
空间复杂度:O(1)
稳定性:不稳定排序

七、归并排序
原理:将待排序序列中相邻的两个有序子序列合并成一个有序序列。
 private static void mergeSort(int[] array){
        mergeSortHelper(array,0,array.length);
     }
    //[left,mid)
    //[mid,right)
     private static void mergeSortHelper(int[] array,int left,int right){
        //不能写成if(left>=right){return;}
        if(right-left<=1){
            return;
        }
        int mid=(left+right)/2;
        mergeSortHelper(array,left,mid);
        mergeSortHelper(array,mid,right);
        merge(array,left,mid,right);
     }
     private static void merge(int[] array,int low,int mid,int high){
        int[] extra=new int[high-low];
        int cur1=low;
        int cur2=mid;
        int index=0;
        while(cur1<mid&&cur2<high){
            //写成<不能保证稳定性
            if(array[cur1]<=array[cur2]){
                extra[index]=array[cur1];
                cur1++;
                index++;
            }
            else{
                extra[index]=array[cur2];
                cur2++;
                index++;
            }
        }
        while(cur1<mid){
            extra[index]=array[cur1];
            cur1++;
            index++;
        }
        while(cur2<high){
            extra[index]=array[cur2];
            cur2++;
            index++;
        }
        for(int i=0;i<high-low;i++){
            array[low+i]=extra[i];
        }
     }

时间复杂度:O(NlogN)
空间复杂度:O(N)
稳定性:稳定排序

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值