排序算法模板

冒泡排序

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
public class BubbleSort {
    public int[] sort(int[] arr){
        int len = arr.length;
        for (int i = 0; i < len - 1; i++) {
            for (int j = 0; j < len - 1 - i; j++) {
                if (arr[j] > arr[j + 1]){
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        return arr;
    }
}

插入排序

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
public class InsertionSort {
    public int[] sort(int[] arr){
        int len = arr.length;
        for (int i = 1; i < len; i++) {
            int preIndex = i - 1;
            int current = arr[i];
            while (preIndex >= 0 && arr[preIndex] > current){
                arr[preIndex + 1] = arr[preIndex];
                preIndex--;
            }
            arr[preIndex + 1] = current;
        }
        return arr;
    }
}

选择排序

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
public class SelectionSort {
    public int[] sort(int[] arr){
        int len = arr.length;
        for (int i = 0; i < len - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < len; j++) {
                if (arr[j] < arr[minIndex]){
                    minIndex = j;
                }
            }
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
        return arr;
    }
}

希尔排序

  • 时间复杂度:O(n²) (这个不是很准)
  • 空间复杂度:O(1)
public class ShellSort {
    public int[] sort(int[] arr){
        int len = arr.length;
        for (int gap = len / 2; gap > 0; gap /= 2) {
            //这是分组,增量啥啥的
            for (int i = gap; i < len; i++) {
                int j = i;
                int current = arr[i];
                //对每个组进行插入排序
                while (j - gap >= 0 && current < arr[j - gap]) {
                    arr[j] = arr[j - gap];
                    j -= gap;
                }
            }
        }
        return arr;
    }
}

归并排序

  • 时间复杂度:O(nlog2N)
  • 空间复杂度:O(n + log2N) (递归) | O(n) (迭代)

递归版

  • 这个是每次递归都要新建一次temp数组
public class MergeSort {
    int[] temp;
    public void sort(int[] arr, int lo, int hi) {
        temp = new int[arr.length];
        if (hi <= lo) return;
        int mid = (hi - lo >> 1) + lo;// ‘-’的优先级大于‘>>’
        sort(arr, lo, mid);
        sort(arr, mid + 1, hi);
        merge(arr, lo, hi, temp);
    }

    public void merge(int[] arr, int lo, int hi,int[] temp) {
        //注意,定位中点坐标最好都这么写,这样不会超int范围
        int mid = (hi - lo >> 1) + lo;
        int i = 0;
        int j = lo,k = mid + 1;
        while(j <= mid && k <= hi){
            if (arr[j] < arr[k]) {
                temp[i++] = arr[j++];
            } else {
                temp[i++] = arr[k++];
            }
        }
        while(j <= mid){//将左边剩余元素填充进temp中
            temp[i++] = arr[j++];
        }
        while(k <= hi){//将右序列剩余元素填充进temp中
            temp[i++] = arr[k++];
        }
        //将temp中的元素全部拷贝到原数组中

        for (int k2 = 0; k2 < i; k2++) {
            arr[k2 + lo] = temp[k2];
        }

    }
}
  • 这种写法不用
public class MergeSort {


    public void sort(int arr[]){
        int[] temp = new int[arr.length];
        sort(arr,0,arr.length - 1,temp);
    }

    public void sort(int[] arr, int lo, int hi,int[] temp) {
        temp = new int[arr.length];
        if (hi <= lo) return;
        int mid = (hi - lo >> 1) + lo;// ‘-’的优先级大于‘>>’
        sort(arr, lo, mid,temp);
        sort(arr, mid + 1, hi,temp);
        merge(arr, lo, hi, temp);
    }

    public void merge(int[] arr, int lo, int hi,int[] temp) {
        //注意,定位中点坐标最好都这么写,这样不会超int范围
        int mid = (hi - lo >> 1) + lo;
        int i = 0;
        int j = lo,k = mid + 1;
        while(j <= mid && k <= hi){
            if (arr[j] < arr[k]) {
                temp[i++] = arr[j++];
            } else {
                temp[i++] = arr[k++];
            }
        }
        while(j <= mid){//将左边剩余元素填充进temp中
            temp[i++] = arr[j++];
        }
        while(k <= hi){//将右序列剩余元素填充进temp中
            temp[i++] = arr[k++];
        }
        //将temp中的元素全部拷贝到原数组中

        for (int k2 = 0; k2 < i; k2++) {
            arr[k2 + lo] = temp[k2];
        }

    }
}

但是不知道为什么,第二种写法用时是第一种写法的好多好多倍,甚至在牛客会爆time
在这里插入图片描述

参考博客

快速排序

基本版(挖坑 + 分治)

public class QuickSort {
    public int[] sort(int[] arr){
        sort(arr,0,arr.length - 1);
        return arr;
    }

    public void sort(int[] arr,int lo,int hi){
        if(lo >= hi)return;
        int i = lo,j = hi;
        int temp = arr[lo];
        int node;
        while (i < j){
            while (j > i && arr[j] >= temp){
                j--;
            }
            while (i < j && arr[i] <= temp){
                i++;
            }
            if (i < j){
                node = arr[i];
                arr[i] = arr[j];
                arr[j] = node;
            }
        }
        arr[lo] = arr[i];
        arr[i] = temp;
        sort(arr,lo,i - 1);
        sort(arr,i + 1,hi);
    }
}

手撸代码写法(模板)

public class QuickSort {
    public int[] sort(int[] arr){
        sort(arr,0,arr.length - 1);
        return arr;
    }
    public void sort(int[] arr,int lo,int hi){
        if(lo >= hi)return;
        int i = lo,j = hi;
        int temp = arr[lo];
        while (i < j){
            while (i < j && arr[j] >= temp)j--;
            if (i < j)arr[i++] = arr[j];
            while (i < j && arr[i] <= temp) i++;
            if (i < j)arr[j--] = arr[i];
        }
        arr[i] = temp;
        sort(arr,lo,i - 1);
        sort(arr,i + 1,hi);
    }
}

参考

  • 为什么归并排序和快速排序平均算法时间复杂度一样,甚至归并排序的空间复杂度小于快排的空间复杂度,我们主流还是用的快速排序呢?

快排能突破nlogn的下界
Arrays.sort里面的快排是做了优化的
大多数的排序情况下,快排的时间复杂度是不到nlogn的,更符合生产情况

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值