java-冒泡排序 插入排序 选择排序

一些定义

1.排序算法的内存消耗(空间复杂度)

算法的内存消耗可以通过空间复杂度来衡量,简单来说就是这个排序要占用多少内存.这里引入一个概念-原地排序,特指空间复杂度为O(1)的排序算法,简单理解,就是不需要额外花费空间(原地:原来多大就多大)的算法.(在接下来的例子中,我会详细解释如何判断是否为原地排序)

2.排序算法的稳定性

稳定性。这个概念是说,如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。

简单举个例子吼: 比如7 9 6(1号) 6(2号) 8 10 排序后如果为 6(一号) 6(二号) 7 8 9 10

则为稳定排序 如果为6(二号) 6(一号) 7 8 9 10则为不稳定排序.

这里有一个小小tips: 笔者在之前理解的时候,认为不稳定排序为相等排序一会先一会后,但实际上,只要相等元素之间原有的先后顺序改变,就是不稳定结构,哪怕一直是后来者居前 也是不稳定的

tips2:大家可能会想:"啊!都是相同的数据了!你还排个锤子排!你给我去spa!",这里举一个小小的例子:订单系统,两名顾客下单的是同一种商品,但是他们的时间总得有个先来后到对吧

冒泡排序

首先是大家喜闻乐见的冒泡排序....

冒泡排序会操作相邻的两个数据。每次操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。

举个栗子

一组数据为 8,7,5,9,6

进行一次"冒泡":(要我说他就不叫冒泡 叫沉底 每次把一个最沉(大)的元素沉到海底)

8>7 -> 7 8 5 9 6

8>5 -> 7 5 8 9 6

8<9 -> 7 5 8 9 6

9>6 -> 7 5 8 6 9

然后在按照这个规则再进行冒泡

代码示例

public static void bubbleSort(int[] a, int n){
        for(int i = 0;i<=n-1;i++){
            for(int j = 0;j<=n-i-2;j++){
                if(a[j]>a[j+1]){
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = tmp;
                }
            }
        }
    }

值得一提的是 冒泡排序是有优化的可能的 如果是 1 3 5 2 4 6这组数据冒泡排序

第一次冒泡1 3 2 4 5 6

第二次冒泡1 2 3 4 5 6

只需要两次冒泡就已经排序好了,但是按照程序运行的话要运行六次才会结束

所以我们对其进行优化,如果没有元素交换 则为已经排序完毕

public static void bubbleSort(int[] a, int n){
        for(int i = 0;i<=n-1;i++){
            boolean jud = true;
            for(int j = 0;j<=n-i-2;j++){
                if(a[j]>a[j+1]){
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = tmp;
                    jud = false;
                }
            }
            if(jud){
                break;
            }
        }
    }

插入排序

借用一下王争老师的图

插入排序逻辑如下

public static void insertsort(int [] arr) {
            if(arr.length<=1) {
                return;
            }
            for(int i = 1;i<arr.length;i++) {
                int value = arr[i];//预选保存当前元素 
                int j = i-1;
                for(;j>=0;j--) {//移动元素 腾出要插的位置 如果后面的大于前面的逐个移动 如果不大于直接跳出循环
                    if(arr[j]>value) {
                        arr[j+1] = arr[j];
                    }else {
                        break;
                    }
                }
                arr[j+1] = value;//插入元素  在j+1处空出的地方
            }
        }

    public static void main(String[] args) {

        int [] arr = {1,3,5,7,9,2,4,6,8,10};
        insertsort(arr);
        System.out.println(Arrays.toString(arr));
}

选择排序

逻辑最简单

0 ~ N-1 找到最小值,在哪,放到0位置上

1 ~ n-1 找到最小值,在哪,放到1 位置上

2 ~ n-1 找到最小值,在哪,放到2 位置上

以此类推

public static void selectionSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        
        for (int i = 0; i < arr.length - 1; i++) {
            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 i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    public static void main(String[] args) {
        int [] arr = {1,3,5,7,9,2,4,6,8,10};
        selectionSort(arr);
        System.out.println(Arrays.toString(arr));
    }

猜你喜欢

转载自blog.csdn.net/chara9885/article/details/129500809
今日推荐