• 算法入门(二):简单排序算法


    原创不易~看完若对你有所帮助,记得点一个赞哈,这就是对我最大的支持了!

    选择排序与冒泡排序

    image.png

    额外空间复杂度

    只需要额外几个变量完成:O(1)

    需要等规模的额外数组:O(N)

    选择排序

    原理之前在第一章节中已经说过了:核心就是遍历找最小值下标,和初始位置替换

    
    
    public class Code01 {
    
        public static void selectionSort(int[] arr){
    
            // 边界条件
    
            if(arr == null || arr.length < 2){
    
                return;
    
            }
    
            for(int i = 0; i < arr.length - 1; i++){ // i~N-1 范围
    
                int minIndex = i;
    
                for(int j = i+1; j < arr.length ; j++){
    
                    // i ~ N-1 中找到最小值下标
    
                    minIndex = arr[j] < arr[minIndex] ? j : minIndex;
    
                }
    
                swap(arr, i, minIndex);
    
            }
    
        }
    
        
    
        public static void swap(int[] arr,int a,int b){
    
            int tmp = arr[a];
    
            arr[a] = arr[b];
    
            arr[b] = tmp;
    
        }
    
    }
    
    • 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

    冒泡排序

    原理:通过遍历原数组,进行大小比较,保证一轮可以将最大值放到最右侧,然后下一轮可以将次大值放到length - 2地方,循环直到结束

    public class Code02 {
    
        public static void bubbleSort(int[] arr){
    
            // 边界条件
    
            if(arr == null || arr.length < 2){
    
                return;
    
            }
    
            for(int e = arr.length - 1; e > 0; e--){
    
                for(int i = 0; i < e ; i++){
    
                    if(arr[i] > arr[i+1]){
    
                        swap(arr,i,i+1);
    
                    }
    
                }
    
            }
    
        }
    
        
    
        public static void swap(int[] arr,int a,int b){
    
            // 另一种基于异或的swap写法
    
            arr[a] = arr[a] ^ arr[b];
    
            arr[b] = arr[a] ^ arr[b];
    
            arr[a] = arr[a] ^ arr[b];
    
        }
    
    }
    
    • 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

    插入排序

    思想

    插入排序很重要的一点思想是保证局部有序

    看0-0范围是否有序,ok

    0-1范围是否有序,如果没有做到,交换arr[0]和arr[1],知道有序,ok

    0-2范围是否有序,判断arr[2]是否更小,是则跟arr[1]交换,还小,跟arr[0]交换,不是,直接跳过这一次,因为前面步骤已经保证0-1有序!直到有序,ok

    image.png

    时间复杂度的波动 - 不稳定

    插入排序和之前冒泡和选择不同的是,他和数据情况是有关系的

    image.png

    例如 7 6 5 4这种数组就是N^2级别

    例如 1 2 3 4这种数组就是N级别,但是冒泡或者选择都仍然需要双重遍历才可以

    算法这课程都是通过O - 最差情况下的常数操作复杂度,所以这个算法仍然是O(N^2)

    但是综合上面其实插入排序在某些数据情况下是会比传统的冒泡和选择排序优秀的,只是最差情况差不多而已。

    实现

    public static void insertionSort(int[] arr){
    
        if(arr == null || arr.length < 2){
    
            return;
    
        }
    
        // 0-0有序
    
        // 0-N希望有序
    
        for(int i = 1; i < arr.length; i++){
    
            for(int j = i - 1;j >= 0 && arr[j] > arr[j+1];j--){
    
                swap(arr,j,j+1);
    
            }
    
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    image.png

  • 相关阅读:
    spring boot自定义配置时在yml文件输入有提示
    Git使用教程:入门到精通
    Spring 注册 Bean 在配置中的定义和使用 Autowired
    一名资深架构师规划Java程序员五年职业生涯指南
    Python中的模块
    反射
    2023数据采集与融合技术实践作业2
    如何理解发明和实用新型具备的实用性?
    double类型数相减有小数误差问题
    figma+windows系统
  • 原文地址:https://blog.csdn.net/sdsh1880gm/article/details/125422538