速过8大排序算法(内含冰冰美图 :D)上

383 阅读4分钟

卧榻睹此盛世颜,此生亦算共枕眠

分为上下两篇完全是为了能放两次冰冰的美照 o(* ̄▽ ̄*)ブ

写这篇博客主要用来记录自己快速过8大排序算法的心路历程,其中不能保证代码是最优解,但是代码都尽量加上注释或者画图,望各位看官手下留情

时间复杂度空间复杂度如下:

冒泡排序

Bubble Sort

解释: 通过对待排序的序列从前到后开始,依次比较相邻两数的大小(这次我要求从小到大排序),若发现逆序(左边大右边小),则交换元素位置 假设待排数组为 634921

每次都将较大的数往后稍,这其中有一个优化算法,如果一轮下来发现没有交换这个过程,证明已经是有序的了

这个冒泡排序也没什么好说的,直接上代码吧

//从小到大排序
public class Bubble {
    public static void main(String[] args) {
        int[] arr ={2,6,1,7,11,7,66,2,7,9,-1};
        sort(arr);
        System.out.println(Arrays.toString(arr));
        //输出:[-1, 1, 2, 2, 6, 7, 7, 7, 9, 11, 66]
    }

    public static void sort(int[] arr) {
       //这里的length-1 是因为下边用的是arr[j]与arr[j+1]比较,防止下标越界
        int len = arr.length-1;
        int temp = 0;
        //该flag用于记录是否移动过数组
        boolean flag = false;
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len-i; j++) {
                if(arr[j] > arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    flag = true;
                }
            }
            if(!flag){
                return;
            }
            //记得下一轮开始之前要将flag重置
            flag = false;
        }
    }
}

选择排序

Selection Sort

解释: 从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置后达到排序的目的 简单来说就是找最小或者最大值,丢在待排序的数组最前面,然后接着往下继续排

public class SelectSort {
    public static void main(String[] args) {
        int[] arr ={2,6,1,7,11,7,66,2,7,9,-1};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void sort(int[] arr) {
        int len = arr.length - 1;
        for (int i = 0; i < len; i++) {
        //用来记录最小值
            int min = arr[i];
        //用来记录最小值所在的下标
            int minIndex = i;
            for (int j = i+1; j < len+1; j++){
                if (min > arr[j]){
                    min = arr[j];
                    minIndex = j;
                }
            }
            if(minIndex != i ){
                //说明最小值有过变化,将待排序的队头与最小的数进行交换
                arr[minIndex] = arr[i];
                arr[i] = min;
            }

        }
    }
}

插入排序

Insertion sort

把 n 个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有 n-1 个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表

public class InsertionSort {
    public static void main(String[] args) {
        int[] arr = {2, 6, 1, 7, 11, 7, 66, 2, 7, 9, -1};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    //要求从小到大排序
    public static void sort(int[] arr) {
        int len = arr.length;

        for (int i = 1; i < len; i++) {
            int insertIndex = i;
            int insertVal = arr[i];

            while (insertIndex >= 1 && insertVal < arr[insertIndex - 1]) {
                //如果当前这个待插入的值比当前的值大,继续往前面找
                //下面这个操作会使arr[insertIndex-1]在数组中有两个相同的值,也就是出了while循环后为什么可以直接将insertVal插入指定位置的原因
                arr[insertIndex] = arr[insertIndex - 1];
                insertIndex--;
            }

            //出来之后,这个insertIndex就是应该插入的位置了
            if (insertIndex != i) {
                arr[insertIndex] = insertVal;
            }
        }
    }
}

希尔排序

Shell Sort

解释:希尔排序是把记录按下标的一定增量分组(gap),对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止 在插入排序中,如果无序表较后的数是一个特别小的数,那么会导致它插入有序表时,有序表中需要有大量的数组移动操作 基于这种现象,提出了缩小增量排序,也就是希尔排序,通过分组完成插入法,从而解决上述问题

public class ShellSort {

    public static void main(String[] args) {
        int[] arr = {2, 6, 1, 7, 11, 7, 66, 2, 7, 9, -1};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    //仍是从小到大
    public static void sort(int[] arr) {
        int len = arr.length;
        for (int gap = len / 2; gap > 0; gap /= 2) {
//从gap开始是因为,前面gap个数都是每组中第一位数,也就是插入算法中默认的有序数组中的第一个数
//并且每次获取的i都相当于从无序表中获取的数,只需要管好自己与前面排好的有序表中的值的位置关系即可
            for (int i = gap; i < len; i++) {
//与之前的插入算法一致
                if (arr[i] < arr[i - gap]) {
                    int shellIndex = i;     
                    int shellVal = arr[i];  
                    while (shellIndex - gap >= 0 && shellVal < arr[shellIndex - gap]) {
                        arr[shellIndex] = arr[shellIndex - gap];
                        shellIndex -= gap;
                    }
                    arr[shellIndex] = shellVal;
                }
            }
        }
    }
}