• 排序算法复杂度



    请添加图片描述

    选择排序

    直接选择排序

    时间复杂度O(n^2)
    空间复杂度O(1)
    稳定

        final static class selectSort{
            public selectSort(int[] arr){
                Sort(arr, arr.length);
            }
    
            private void Sort(int[] arr, int n) {
                for (int i = 0; i < n; i++) {
                    int min = i;
                    for (int j = i; j < n; j++) {
                        if(arr[min] > arr[j]){
                            min = j;
                        }
                    }
                    swap(arr, i, min);
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    堆排序

    时间复杂度不太好算啊,看看这个:https://blog.csdn.net/YuZhiHui_No1/article/details/44258297
    建堆时间复杂度O(n)
    堆排序时间复杂度O(nlogn)
    空间复杂度O(1)

        final static class heapSort{
            //堆排序用new PriorityQueue<Integer>((o1, o2)->(o1 - o2));
            //https://www.runoob.com/w3cnote/heap-sort.html
            //https://zhuanlan.zhihu.com/p/45725214
            public heapSort(int[] arr){
                if(arr.length < 2) return;
                int len = arr.length;
                BuildMaxHeap(arr, len);
                for(int i=len-1; i>0; i--){
                    swap(arr, 0, i);
                    len--;
                    heapify(arr, 0, len);
                }
            }
            public void BuildMaxHeap(int[] arr, int len){
                for(int i=(int) Math.floor(len / 2); i>=0; i--){
                    heapify(arr, i, len);
                }
            }
            public void heapify(int[] arr, int i, int len){
                int left = i * 2 + 1;
                int right = i * 2 + 2;
                int larger = i;
                if(left < len && arr[left] > arr[larger]){
                    larger = left;
                }
                if(right < len && arr[right] > arr[larger]){
                    larger = right;
                }
                if(larger != i){
                    swap(arr, i, larger);
                    //交换之后larger位置为较小的值,继续向下调整
                    heapify(arr, larger, len);
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    插入排序

    直接插入排序

    时间复杂度O(n^2)
    空间复杂度O(1)
    稳定

        final static class insertSort{
            public insertSort(int[] arr){
                Sort(arr, arr.length);
            }
    
            private void Sort(int[] arr, int n) {
                for (int i = 1; i < n; i++) {
                    int tmp = arr[i];
                    int j = i - 1;
                    while (j >= 0 && arr[j] > tmp) {
                        arr[j+1] = arr[j];
                        j--;
                    }
                    arr[j+1] = tmp;
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    希尔排序

    插入排序的改良,增加了步长
    时间复杂度O(nlogn)
    空间复杂度O(1)

        final static class shellSort{
            shellSort(int[] arr){
                Sort(arr, arr.length);
            }
    
            private void Sort(int[] arr, int n) {
                int gap = n;
                do{
                    gap = gap / 3 + 1;
                    for (int i = gap; i < n; i++) {
                        int tmp = arr[i];
                        int j = i - gap;
                        while (j >= 0 && arr[j] > tmp) {
                            arr[j + gap] = arr[j];
                            j -= gap;
                        }
                        arr[j + gap] = tmp;
                    }
                }while (gap > 1);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    交换排序

    冒泡排序

    时间复杂度O(n^2)
    空间复杂度O(1)
    稳定

        final static class BubbleSort{
            public BubbleSort(int[] arr){
                Sort(arr, arr.length);
            }
    
            private void Sort(int[] arr, int n) {
                for (int i = 0; i < n; i++) {
                    for (int j = 1; j < n - i; j++) {
                        if(arr[j-1] > arr[j]){
                            swap(arr, j-1, j);
                        }
                    }
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    快速排序

    时间复杂度O(nlogn)
    最坏时间复杂度O(n^2) 当划分产生的两个子问题分别包含 n-1 和 0 个元素时,最坏情况发生。
    空间复杂度O(logn) 其中sort递归调用生成partitionIndex

        final static class quickSort{
            public quickSort(int[] arr){
                Sort(arr, 0, arr.length-1);
            }
            public void Sort(int[] arr, int l, int r){
                if(l < r){
                    int partitionIndex = partition(arr, l, r);
                    Sort(arr, l, partitionIndex-1);
                    Sort(arr, partitionIndex+1, r);
                }
            }
            public int partition(int[] arr, int l, int r){
                int pivot = l;
                int index = pivot + 1;
                for(int i=index; i<=r; i++){
                    if(arr[i] < arr[pivot]){
                        swap(arr, i, index++);
                    }
                }
                swap(arr, pivot, index-1);
                return index-1;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    归并排序

    时间复杂度O(nlogn)
    空间复杂度O(n)
    这个稍微想一下就行了,不是特别难

        final static class mergeSort{
            public mergeSort(int[] arr) {
                Sort(arr, 0, arr.length - 1);
            }
            public void Sort(int[] arr, int l, int r){
                if(l < r){
                    int mid = (l + r)/2;
                    Sort(arr, l, mid);
                    Sort(arr, mid+1, r);
                    merge(arr, l, mid, r);
                }
            }
            public void merge(int[] arr, int l, int mid, int r){
                int[] help = new int[r-l+1];
                int count = 0;
                int p = l, q = mid + 1;
                while(p <= mid && q <= r){
                    help[count++] = arr[p] < arr[q] ? arr[p++] : arr[q++];
                }
                while(p <= mid){
                    help[count++] = arr[p++];
                }
                while(q <= r){
                    help[count++] = arr[q++];
                }
                for(int i = 0; i < help.length; i++){
                    arr[l + i] = help[i];
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    桶排序

    计数排序

    计数排序有点坑啊
    他先找到数组中最大和最小值,然后用这个二者的差值作为计数数组的长度
    如果我数组中就三个元素[1, 2, 100]就不合适了
    时间复杂度O(n + k)
    空间复杂度O(n + k)

        final static class countSort{
            countSort(int[] arr){
                Sort(arr, arr.length);
            }
    
            private void Sort(int[] arr, int n) {
                int max = arr[0];
                int min = arr[0];
                for (int i = 0; i < n; i++) {
                    if (max < arr[i]) {
                        max = arr[i];
                    }
                    if (min > arr[i]) {
                        min = arr[i];
                    }
                }
                // 最大最小元素之间范围[min, max]的长度
                int offset = max - min + 1;
                // 1. 计算频率,在需要的数组长度上额外加1
                int[] count = new int[offset + 1];
                for (int i = 0; i < n; i++) {
                    // 使用加1后的索引,有重复的该位置就自增
                    count[arr[i] - min + 1]++;
                }
                // 2. 频率 -> 元素的开始索引
                for (int i = 0; i < offset; i++) {
                    count[i + 1] += count[i];
                }
    
                // 3. 元素按照开始索引分类,用到一个和待排数组一样大临时数组存放数据
                int[] aux = new int[n];
                for (int i = 0; i < n; i++) {
                    // 填充一个数据后,自增,以便相同的数据可以填到下一个空位
                    aux[count[arr[i] - min]++] = arr[i];
                }
                // 4. 数据回写
                for (int i = 0; i < n; i++) {
                    arr[i] = aux[i];
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    基数排序

    我复制粘贴的,不太想看了
    时间复杂度O(n * m)
    空间复杂度O(m)

    final static class RadixSort{
            public RadixSort(int[] arr) {
                // 对 arr 进行拷贝,不改变参数内容
                int[] array = Arrays.copyOf(arr, arr.length);
    
                int maxDigit = getMaxDigit(array);
                Sort(arr, maxDigit);
            }
    
            /**
             * 获取最高位数
             */
            private int getMaxDigit(int[] arr) {
                int maxValue = getMaxValue(arr);
                return getNumLenght(maxValue);
            }
    
            private int getMaxValue(int[] arr) {
                int maxValue = arr[0];
                for (int value : arr) {
                    if (maxValue < value) {
                        maxValue = value;
                    }
                }
                return maxValue;
            }
    
            protected int getNumLenght(long num) {
                if (num == 0) {
                    return 1;
                }
                int lenght = 0;
                for (long temp = num; temp != 0; temp /= 10) {
                    lenght++;
                }
                return lenght;
            }
    
            private int[] Sort(int[] arr, int maxDigit) {
                int mod = 10;
                int dev = 1;
    
                for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
                    // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10)
                    int[][] counter = new int[mod * 2][0];
    
                    for (int j = 0; j < arr.length; j++) {
                        int bucket = ((arr[j] % mod) / dev) + mod;
                        counter[bucket] = arrayAppend(counter[bucket], arr[j]);
                    }
    
                    int pos = 0;
                    for (int[] bucket : counter) {
                        for (int value : bucket) {
                            arr[pos++] = value;
                        }
                    }
                }
    
                return arr;
            }
    
            /**
             * 自动扩容,并保存数据
             *
             * @param arr
             * @param value
             */
            private int[] arrayAppend(int[] arr, int value) {
                arr = Arrays.copyOf(arr, arr.length + 1);
                arr[arr.length - 1] = value;
                return arr;
            }
        }
        final static class mergeSort{
            public mergeSort(int[] arr) {
                Sort(arr, 0, arr.length - 1);
            }
            public void Sort(int[] arr, int l, int r){
                if(l < r){
                    int mid = (l + r)/2;
                    Sort(arr, l, mid);
                    Sort(arr, mid+1, r);
                    merge(arr, l, mid, r);
                }
            }
            public void merge(int[] arr, int l, int mid, int r){
                int []help = new int[r-l+1];
                int count = 0;
                int p = l, q = mid + 1;
                while(p<=mid && q<=r){
                    help[count++] = arr[p] < arr[q] ? arr[p++] : arr[q++];
                }
                while(p<=mid){
                    help[count++] = arr[p++];
                }
                while(q<=r){
                    help[count++] = arr[q++];
                }
                for(int i=0; i<help.length; i++){
                    arr[l+i] = help[i];
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
  • 相关阅读:
    记录--怎么实现一个3d翻书效果
    动态分析股票走势算法图,股票趋势预测算法
    GpsAndMap模块开源,欢迎测评
    uniapp中使用canvas做审批签名
    Spring Cloud Tencent 迎来 1.7.0 大版本更新,欢迎体验
    常见协议UDP和TCP详解
    SpringBoot异步任务、邮件任务、定时任务
    公益培训报名小程序
    IDEA2021配置Maven
    修复MybatisX1.4.17版本插件误报@Mapkey is required错误
  • 原文地址:https://blog.csdn.net/superprintf/article/details/125501745