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

214 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

选择排序与冒泡排序

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;

    }

}

冒泡排序

原理:通过遍历原数组,进行大小比较,保证一轮可以将最大值放到最右侧,然后下一轮可以将次大值放到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];

    }

}

插入排序

思想

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

看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);

        }

    }

}

image.png