Java-数据结构篇-七种排序的简要总结

本文总结了Java中的七大排序算法:冒泡排序、选择排序、直接插入排序、Shell排序、快速排序、归并排序和堆排序。详细介绍了它们的时间复杂度、空间复杂度、稳定性和代码示例,特别指出快速排序和归并排序在不同情况下的效率特点,以及优化策略。
摘要由CSDN通过智能技术生成

总结:七种排序

一、冒泡排序(以下皆以从小到大排序为例)
1.时间复杂度

平均情况:O(n^2)
最好情况:O(n)
最坏情况:O(n^2)

2.空间复杂度:O(1)
3.稳定性:稳定(没有发生跳跃式的交换)
4.代码示例
public static int[] bubbleSort(int[] arr) {
        if(arr == null || arr.length <= 1){
            return arr;
        }
        for(int i=0;i<arr.length-1;i++){
            int a=0;
            for(int j=0;j<arr.length-1-i;j++){//每次循环结束后最后一个元素为当前最大元素
                if(arr[j]>arr[j+1]){//将大数往后移
                    int tmp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=tmp;
                    a++;
                }
            }
            if(a==0){//所有数有序
                break;
            }
        }
        return arr;
}
二、选择排序(从待排序数字的后面找到比当前待排序数字小的数字进行交换)
1.时间复杂度

平均情况:O(n^2)
最好情况:O(n^2)
最坏情况:O(n^2)

2.空间复杂度:O(1)
3.稳定性:不稳定(发生了跳跃式的交换)
4.代码示例
public static int[] selectionSort(int[] arr) {
        for(int i = 0;i < arr.length;i++){
            for(int j = i + 1;j < arr.length;j++){
                if(arr[j] < arr[i]){
                    int tmp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = tmp;
                }
            }
        }
        return arr;
}

三、直接插入排序(越有序越快)
1.时间复杂度

平均情况:O(n^2)
最好情况:O(n)
最坏情况:O(n^2)

2.空间复杂度:O(1)
3.稳定性:稳定
4.代码示例
public static int[] insertionSort(int[] arr){
        for(int i = 1;i < arr.length;i++) {
            int tmp = arr[i],j=0;
            for (j = i - 1; j >= 0; j--) {
                if(arr[j] > tmp){//将比i大的往后移
                    arr[j+1] = arr[j];
                }else{
                    break;
                }
            }
            arr[j+1] = tmp;//将i放回
        }
        return arr;
}

四、Shell排序(组内进行有序(插入排序))
1.时间复杂度

平均情况:O(n^1.3)
最好情况:O(n)
最坏情况:O(n^2)

2.空间复杂度:O(1)
3.稳定性:不稳定
4.代码示例
public static int[] shellSort(int[] arr,int gap) {
        for(int i = gap;i < arr.length;i++) {
           int tmp = arr[i], j = 0;
           for (j = i - gap; j >= 0; j = j - gap) {
                if(arr[j] > tmp){
                    arr[j + gap] = arr[j];
                }else{
                    break;
                }
            }
            arr[j + gap] = tmp;
        }
        return arr;
}
五、快速排序
1.时间复杂度

平均情况:O(nlog2n)
最好情况:O(nlog2n)
最坏情况:O(n^2)

2.空间复杂度:O(log2n)
3.稳定性:不稳定
4.代码示例

         (1)快速排序的递归算法

public static int partion(int[] array,int low,int high){
        int tmp = array[low];
        int count = 1;
        while(low<high){
            if(count%2==1) {//利用count实现前后的轮替交换
                if (array[high]< tmp) {//从后面找小的
                    array[low]=array[high];
                    count++;
                }else {
                    high--;
                }
            }else {
                if(array[low]>tmp){//从前面找大的
                    array[high] = array[low];
                    count++;
                }else {
                    low++;
                }
            }
        }
        array[low]=tmp;
        return low;
}
public static void quick(int[] array,int low,int high){
        int par = partion(array,low,high);
        if(par > low+1){
            quick(array,low,par-1);
        }
        if(par<high-1){
            quick(array,par+1,high);
        }
}
public static void quickSort(int[] array){
        quick(array,0,array.length-1);
}

         (2)快速排序的非递归算法

 public static int partion(int[] array,int low,int high){
        int tmp = array[low];
        int count = 1;
        while(low<high){
            if(count%2==1) {
                if (array[high]< tmp) {
                    array[low]=array[high];
                    count++;
                }else {
                    high--;
                }
            }else {
                if(array[low]>tmp){
                    array[high] = array[low];
                    count++;
                }else {
                    low++;
                }
            }
        }
        array[low]=tmp;
        return low;
}
    public static void quickSort1(int[] array){
        int len = (int)(log((double)array.length)/log((double)2));
        int[] stack = new int[2*len];//用栈存储low和high
        int top = 0 ;
        int low = 0 ;
        int high = array.length-1;
        int par = partion(array,low,high);
        if(par>low+1){
            stack[top] = low;
            top++;
            stack[top] = par-1;
            top++;
        }
        if(par<high-1){
            stack[top] = par+1;
            top++;
            stack[top] = high;
            top++;
        }
        while(top!=0){
            top--;
            high=stack[top];
            top--;
            low = stack[top];
            par = partion(array,low,high);
            if(par>low+1){
                stack[top] = low;
                top++;
                stack[top] = par-1;
                top++;
            }
            if(par<high-1){
                stack[top] = par+1;
                top++;
                stack[top] = high;
                top++;
            }
        }
}
5.快速排序的优化(以下两种是对基准选取的优化)

         (1)随机

public static int selectPivotRandom(int array[],int low,int high){
        Random random = new Random();
        int pivotPos = random.nextInt(high-low+1)+low;
        int tmp = array[low];
        array[low]=array[pivotPos];
        array[pivotPos]=tmp;
        return array[low];
}

         (2)取中

public static void midThree(int[] array,int low,int high){
        int mid = (high+low)/2;
        if(array[low]>array[high]){//实现mid<low<high
            int tmp = array[low];
            array[low]=array[high];
            array[high]=tmp;
        }
        if(array[mid]>array[low]){
            int tmp = array[low];
            array[low]=array[mid];
            array[mid]=tmp;
        }
        if(array[mid]>array[high]){
            int tmp = array[high];
            array[high]=array[mid];
            array[mid]=tmp;
        }
}
六、归并排序(使每个子序列有序,再使子序列段间有序)
1.时间复杂度

平均情况:O(nlog2n)
最好情况:O(nlog2n)
最坏情况:O(nlog2n)

2.空间复杂度:O(n)
3.稳定性:稳定
4.代码示例
public static void merge(int[] array,int gap){
        int[] tmpArr = new int[array.length];
        int i = 0;
        int s1 = 0;
        int e1 = s1+gap-1;
        int s2 = e1+1;
        int e2 = s2+gap-1 < array.length ? s2+gap-1:array.length-1;
        while(s2<array.length){
            while(s1<=e1&&s2<=e2){
                if(array[s1]<array[s2]){
                    tmpArr[i]=array[s1];
                    i++;
                    s1++;
                }
                if(array[s2]<array[s1]){
                    tmpArr[i]=array[s2];
                    i++;
                    s2++;
                }
            }
            if(s1>e1){
                while(s2<=e2){
                    tmpArr[i]=array[s2];
                    i++;
                    s2++;
                }
            }
            if(s2>e2){
                while(s1<=e1){
                    tmpArr[i]=array[s1];
                    i++;
                    s1++;
                }
            }
            s1 = e2+1;
            e1 = s1+gap-1;
            s2 = e1+1;
            e2 = s2+gap-1 < array.length ? s2+gap-1:array.length-1;
        }
        while(s1<array.length){
            tmpArr[i] = array[s1];
            i++;
            s1++;
        }
        for(int j = 0 ;j<array.length;j++){
            array[j] = tmpArr[j];
        }
}
    public static void mergeSort(int[] array){
        for(int i = 1;i<array.length;i*=2){//循环使每次的子段长度增加
            merge(array,i);
        }
    }
七、堆排(建立大根堆)
1.时间复杂度

平均情况:O(nlog2n)
最好情况:O(nlog2n)
最坏情况:O(nlog2n)

2.空间复杂度:O(1)
3.稳定性:不稳定
4.代码示例
	public static void adjust(int[] array,int start,int end){
        int tmp = array[start];
        for (int i = 2*start+1; i <= end ; i = 2*i+1) {
            //判断是否有右孩子,如果有,找到左右孩子的最大值。
            if((i < end) && array[i] < array[i+1]) {
                i++;
            }//肯定i是最大值的下标
            if(array[i] > tmp) {
                array[start] = array[i];
                start = i;
            }else {
                break;
            }
        }
        array[start] = tmp;
    }
    public static void heapSort(int[] array){
        for(int i = (array.length-1-1)/2;i>=0;i--){//建立大根堆
            adjust(array,i,array.length-1);
        }
        int tmp = 0;
        for (int i = array.length-1; i >0 ; i--) {
            tmp = array[i];
            array[i] = array[0];
            array[0]=tmp;
            adjust(array,0,i-1);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值