最详细的剖析排序算法之冒泡排序,选择排序,插入排序,满满干货,绝对有干货

前言

这段时间一直在研究算法,首先从基础研究,那就是排序了,
为什么我要把这三个放到一起呢?
首先这三个算法最简单,入门基础
其次因为通过这段时间的学习我发现这"哥三"总体上有很多共性放在一起很合适
但细节方面有稍微有点不同,
下面我来把这"哥三"整的明明白白的

1、冒泡排序

首先说明基本上所有的排序算法默认都是从小到大的顺序
排序思想: 冒泡排序它是通过相邻俩个数比大小.大的数放后面,从头开始比完所有的数.举个例子,12位置比,谁大谁在后面,然后23,34,45这样一直比下去,这样过一遍所有的数,最后面的数肯定是最大的,这就排好了一个数,在从头开始,一共比n-1次,就能从小到大排好所有的数
下面上代码

private static void bubbleSort(int [] arr){
    //外层循环确定比较的轮数
    for (int i = 0; i < arr.length - 1; i++) {
     //内层循环是每轮比较次数,
       因为每轮比较都能排好一个数,
       每轮减去之前比较的轮数就是比较的次数
        for (int j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j+1]){
                //下面的代码是异或交换俩个数,不懂的百度一下
                arr[j] = arr[j] ^ arr[j + 1];
                arr[j + 1] = arr[j] ^ arr[j + 1];
                arr[j] = arr[j] ^ arr[j + 1];
            }
        }
    }
}

总结
时间复杂度O(n^2),额外空间复杂度O(1)
排序步骤固定不依赖数据本身,数据不会影响排序快慢
可以做到稳定性

2、选择排序

选择排序跟冒泡排序一开始我是分不清楚的,老搞混,主要是思想没理解

冒泡排序通过比较数字大小来找这个数字位置,
选择排序是先定好位置再通过比较大小来找这个数字

排序思想: 先假设第一个位置数字最小,然后头到尾比较最小位置和最小位置后面的数,如果后面的数字比最小位置数字小就交换位置,举个例子,21比,31比,41比,一直比完,过程中,小就交换位置
下面上代码

public static void selectSort(int [] arr){
    //外层循环比较的轮数
    for (int i = 0; i < arr.length - 1; i++) {
     //内层循环每轮比较次数,每轮确定一个头位置参照冒泡注释
        int min = i;
        for (int j = i + 1; j < arr.length; j++) {
           if(arr[j] < arr[min]){
               min = j;
           }
        }
        if(min != i){
            arr[i] = arr[i] ^ arr[min];
            arr[min] = arr[i] ^ arr[min];
            arr[i] = arr[i] ^ arr[min];
        }
    }
}

总结
时间复杂度O(n^2),额外空间复杂度O(1)
排序步骤固定不依赖数据本身,数据不会影响排序快慢
不可以做到稳定性

3、插入算法

插入算法比较好理解就相当于你打扑克摸牌,假设你爱把手里扑克牌从小到大排放,没摸一张就从后面依次往前找它的位置

排序思想 : 假设第一个位置是排好序的,后面每来一个数就跟前一个数比大小,如果小,就继续向前比,直到它是最小的.举个例子,前面有序的一组数14569,然后0来了,跟前一个比,发现自己小,继续向前,直到它最小
下面上代码

private static void insertSort(int [] arr){
   头到尾过一遍
    for (int i = 1; i < arr.length; i++) {
    前面是有序的,前面有数且比它大,就往前走继续比
        for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]  ; j--) {
            arr[j] = arr[j] ^ arr[j + 1];
            arr[j + 1] = arr[j] ^ arr[j + 1];
            arr[j] = arr[j] ^ arr[j + 1];
        }
    }
}

如果一组数是123456,你想想他们三的排序流程,如果是654321你再想想

总结
时间复杂度O(n^2),额外空间复杂度O(1)
排序步骤依赖数据本身,数据会影响排序快慢
最好情况O(n),最坏情况O(n^2)
可以做到稳定性

最后总结

冒泡排序和选择排序在实际中几乎不用
它们三都是时间复杂度O(n^2),额外空间复杂度O(1)
冒泡和插入都可以做到稳定性,选择不行
冒泡和选择快慢跟数据无关,插入有关

敬请期待下一篇介绍常用的排序算法之归并,快排,堆排

你可能感兴趣的:(数据结构和算法)