直接插入排序、冒泡排序和简单选择排序以及Java代码实现(平均时间复杂度为O(n^2)的排序方法)

直接插入排序、冒泡排序和简单选择排序(平均时间复杂度为O(n^2)的排序方法)

(1)O(n^2)的时间复杂度是比较大的,所以不适用于大量数据。
(2)这三种方法都是基于比较和移动的,基于比较和移动的排序算法时间复杂度主要考虑比较和移动的次数
(3)这三种方法都是内部排序,元素的存储和额外的空间开销都在内存内。外部排序指的是需要同时利用外存和内存,元素在外存和内存间移动。(可能元素的数量比较大)
(4)稳定性:对于序列中相等的两个元素i,j,如果排序后元素i,j顺序颠倒了,这个算法就是不稳定的,反之稳定

1.直接插入排序

(1)插入排序概念:对于每一个待排序序列分解为已排序的序列s和一个元素e,把e按照大小顺序插入到已排序序列s中。
(2)直接插入排序
设表为L[1,2,…,n],每次都把L[i]插入到有序表L[1,2,3,…,i-1]中构成新的有序表L[1,2,3,…,i],直到n=i(插入前提必须是L[i-1]和L[i]逆序)

[1]平均时间复杂度和最坏时间复杂度都是O(n^2),如果列表本来就有序,即最好的情况下时间复杂度为O(n)
[2]空间复杂度O(1)
[3]稳定性:触发插入的前提是L[i-1]和L[i]逆序,所以不可能改变相等元素的相对次序,所以是稳定的

Java语言代码实现:

Java比较大小有3种情况:
[1]基本类型int,float,long,double,这时候使用>(=) or <(=)就可以
[2]待比较对象实现了Comparable接口,调用o1.compareTo(o2)方法就可以,如果o1比o2小,则返回负数,大则返回正数,相等则返回0,int、float、long和double可以自动装箱为Integer、Float、Long和Double,它们都实现了Comparable接口

        Integer a = 1;
        Integer b = 2;
        //打印 -1
        System.out.println(a.compareTo(b));

[3]写一个Comparator比较器,重写compare方法,最终效果上类似于Comparable接口
‘小’是人为定义的,假如我刚好想要从大到小排序整数,下面这个比较器就可以,‘越大越小’

Comparator<Integer> c = new Comparator<Integer>() {
    
    
            @Override
            public int compare(Integer i1, Integer i2) {
    
    
                if (i1 < i2) {
    
    
                    return 1;
                } else if (i1 > i2) {
    
    
                    return -1;
                } else {
    
    
                    return 0;
                }
            }
        };

为了简化实现,就用int举个例子:

    public static void insertSort(int[] array) {
    
    
        for (int i = 1; i < array.length; i++) {
    
    
            //逆序时候才触发
            if (array[i - 1] > array[i]) {
    
    
                //取出这个元素
                int elem = array[i];
                int j;
                for (j = i - 1; j >= 0; j--) {
    
    
                    if (array[j] > elem) {
    
    
                        array[j + 1] = array[j];
                    } else {
    
    
                        break;
                    }
                }
                array[j + 1] = elem;
            }
        }
    }

    @Test
    public void test() {
    
    
        int[] a = {
    
    1, 2, 3, 10, -1, 8, 7};
        System.out.println(Arrays.toString(a));
        insertSort(a);
        System.out.println(Arrays.toString(a));

    }

控制台打印结果:

在这里插入图片描述

2.冒泡排序

(1)冒泡排序属于交换排序,根据元素比较结果交换元素,最终达到排序的目的。
(2)冒泡排序的过程:
设列表L[1,2,3,…,n]
第1趟,L[1-n]中从后向前两两比较,如果前者大于后者,则交换,最终结果L[1]是最小值,如果没有逆序情况直接结束
第2趟,L[2-n]中从后向前两两比较,如果前者大于后者,则交换,最终结果L[2]是次小值,如果没有逆序情况直接结束

第n-1趟,L[n-1,n]执行相同的操作完成排序

[1]空间复杂度O(1)
[2]时间复杂度最好情况下O(n),最坏的情况和平均的情况都是O(n^2)
[3]稳定性:两两比较,如果前者大于后者,则交换,相等情况下不可能交换,所以这个算法是稳定的

代码实现如下:

    public static void bubbleSort(int[] array) {
    
    
        // n-1趟,i表示每一趟的起始元素值
        for (int i = 0; i < array.length - 1; i++) {
    
    
            boolean swap = false;
            for (int j = array.length - 1; j > i; j--) {
    
    
                if (array[j] < array[j - 1]) {
    
    
                    int tmp = array[j];
                    array[j] = array[j - 1];
                    array[j - 1] = tmp;
                    swap = true;
                }
            }
            // 如果没交换过说明有序
            if (!swap) {
    
    
                break;
            }
        }
    }

    @Test
    public void testBubbleSort() {
    
    
        int[] a = {
    
    1, 2, 3, 10, -1, 8, 7};
        System.out.println(Arrays.toString(a));
        bubbleSort(a);
        System.out.println(Arrays.toString(a));

    }

控制台打印结果:
在这里插入图片描述

3.简单选择排序

(1)属于选择排序,选择排序指的是第i趟,在n-i+1个元素中选择最小值,加入到新序列中。
(2)简单选择排序过程:
设列表L[1,2,3,…,n]
第1趟,在L[1-n]个元素中选择最小值索引j,L[j]和L[1]交换
第2趟,在L[2-n]个元素中选择最小值索引j,L[j]和L[2]交换

第n-1趟,在L[n-1 - n]个元素中选择最小值索引j,L[j]和L[2]交换

[1]空间复杂度O(1)
[2]时间复杂度最好最坏平均都是O(n^2),不论交换的次数,选择的次数不会变化
[3]稳定性:如果L={x11,x12,x2}(x11=x12>x2),算法运行结束后结果变成了L={x2,x12,x11},相等元素位置先后顺序交换了,所以简单选择排序是不稳定的

代码实现:

    public static void simpleSort(int[] array) {
    
    
        for (int i = 0; i < array.length - 1; i++) {
    
    
            int min = array[i];
            int minIndex = i;
            for (int j = i + 1; j < array.length; j++) {
    
    
                if (array[j] < min) {
    
    
                    min = array[j];
                    minIndex = j;
                }
            }
            int tmp = array[i];
            array[i] = array[minIndex];
            array[minIndex] = tmp;

        }
    }

    @Test
    public void testSimpleSort() {
    
    
        int[] a = {
    
    1, 2, 3, 10, -1, 8, 7};
        System.out.println(Arrays.toString(a));
        simpleSort(a);
        System.out.println(Arrays.toString(a));

    }

控制台结果:
在这里插入图片描述

以后还会介绍一些时间复杂度到达O(n^1.5) or O( n*log(n) ) or O(n)的排序算法。

转载请注明出处,谢谢合作

猜你喜欢

转载自blog.csdn.net/weixin_42111859/article/details/104132520