常见的排序算法总结

平时一直做项目,业务逻辑,对算法这块逐渐有了生疏
今天有空总结一下排序算法
1)冒泡排序
冒泡排序的原理就是两两相比,从小到大的话前面比后面大就交换,从大到大的话前面比后面小就交换,比如有一组数[1,10,5,3,2]
如何对它做排序(比如从小到大)
第一步:
[1,10,5,3,2]源数据
[1,10,5,3,2]//1<10     不交换
[1,5,10,3,2]//10>5     交换
[1,5,3,10,2]//10>3    交换
[1,5,3,2,10]//10>2    交换
这样,最高位的数10一定是最大的,所有第二步交换的时候就只对[1,5,1,2]做判断
第二步:
[1,5,3,2]源数据
[1,5,3,2]//1<5     不交换
[1,3,5,2]//5>3    交换
[1,3,2,5]//5>2    交换
一样,去掉最大的5
第三步:
[1,3,2]源数据
[1,3,2]//1<3     不交换
[1,2,3]//3>2    交换
一样,去掉最大的3
第四步:
[1,2]源数据
[1,2]//1<2     不交换
到此,我们发现只剩下最后两个数了,那么比较也就结束了,这里所说的比较到最后两个数是比较的最大限度,
当然在程序里可以控制当执行比较的时候某轮比较一次交换也没发生,那么,就可以提前终止比较
下面是代码
        Integer[] a = new Integer[] {1,10,5,3,2};
        //第一层循环控制比较的轮数
        for (int i = 0; i < a.length-1; i++) {
            boolean flg=false;
            //第二层循环控制每一轮从第几位开始,到第几位结束,也就是上述的去掉最大值的过程
            for (int j = 0; j < a.length-i-1; j++) {
                if (a[j] > a[j + 1]) {
                    flg=true;
                    int temp = a[j + 1];
                    a[j + 1] = a[j];
                    a[j] = temp;
                }
            }
            if(!flg){break;}
        }
优点:冒泡排序实现起来比较简单,空间复杂度低,稳定;
缺点:时间复杂度高,循环走的多费时间
2)选择排序
选择排序是分区排序,比如从小到大排序,开始先从数组选出最大的数放在最高位,然后在n-1个数里再选出最大的放在次高位,以此类推,当选到只剩一个数时停止

[1,10,5,3,2]  源数据
选出10,放在2的位置,数据变为[1,2,5,3,10]
选出5,放在3的位置,数据变为[1,2,3,5,10]
选出3,不用移位
选出2,不用移位
代码
        int maxindex = a.length - 1;
        while (true) {
            //保存一轮比较后的最大值和它的下标
            int max = a[maxindex];
            int maxnow = a[0];
            int maxnowindex = 0;
            for (int i = 1; i < maxindex; i++) {
                if (a[i] > maxnow) {
                    maxnow = a[i];
                    maxnowindex = i;
                }
            }
            //将一轮选出的最大值跟假定的最大值作比较
            if (maxnow > max) {
                a[maxindex] =maxnow;
                a[maxnowindex] =max;

            }
            //备选数据个数-1
            maxindex--;
            //最后一个数据终止
            if (maxindex == 0) {
                break;
            }
        }
优点:数据移动的次数已知;
缺点:不稳定
3)插入排序 插入排序跟选择排序有点相似,都是把无序数据列中的一个数据放到有序的数据列,区别是选择排序你从无序数据列选出来的肯定是最大或者最小值,并且对于你这个将要插入到
有序数据列的数的位置也是固定的,是依次插入的。然而对于插入排序,你不知道无序数据列中选出来的数据会被放到有序数据列的哪个位置,只有这个数去有序数据列寻找到自己的位置时,它的位置
才会被确定。插入排序就像是打扑克牌,你手里拿着的牌是你排好序的,当你拿起这张牌没看它的点时这张牌的位置是不确定的,只有你看了牌的大小并且跟手牌比较之后,这张牌插的位置才会被确定。
    如
    [1,10,5,3,2]  源数据    
    [1,10,5,3,2]  拿起第一张牌
    [1,10,5,3,2]  拿起第二张牌
    [1,5,10,3,2]  拿起第三张牌
    [1,3,5,10,2]  拿起第四张牌
    [1,2,3,5,10]  拿起第五张牌
        //如果把无序数据比作牌堆,这层循环控制你拿起牌的次数
        for (int i = 0; i < a.length; i++) {
        //这层循环完成了你看牌并且和手牌比较了之后把拿起的牌放进了手牌
            for (int j = i; (j > 0) && a[j - 1] > a[j]; j--) {
                int temp = a[j];
                a[j] = a[j - 1];
                a[j - 1] = temp;

            }
        }

优缺点:时间复杂度根据具体情况而定,空间复杂度一般,稳定性也根据实际情况,主要取决于元素的相对位置的改变,数据少速度快;

4)希尔排序(插入排序改进版)

 

你可能感兴趣的:(算法)