冒泡&插入&选择(详解及对比)

冒泡排序

核心思想

相邻元素两两相比,每一次冒泡都可以找出最大/最小的元素

代码(附详细注释)

代码是普通冒泡的升级版:如果某一次冒泡循环,没有元素移动,就证明已经是有序数组了,后面就无需再循环了

public void bubbleSort(int[] nums){
	//冒泡的次数(大循环)
	for (int i = 0; i < nums.length-1; i++) {
		// 提前退出冒泡循环的标志位(每一次循环后重置为false)
    	boolean flag = false;
    	//两两依次比较(小循环)
    	for (int j = 0; j < nums.length - 1 - i; j++) {
        	if (nums[j] > nums[j + 1]) {
                int temp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = temp;
                //有数据交换 则置为true
                flag = true;
            }
        }
        //无数据交换 提前退出
        if(!flag) break;
    }
}

性能分析

  • 冒泡排序是原地排序

  • 冒泡排序是稳定的排序

  • 时间复杂度最好O(n),最坏O(n^2)


插入排序

核心思想

每次从未排序的区间拿出一个元素,在已排序区间找到合适的地方插入

初始的已排序区间是第一个元素

我认为插入排序的关键点就是区分开已排序空间未排序空间

插入比冒泡强在哪(效率)

冒泡排序的数据交换要比插入排序的数据移动要复杂,冒泡排序需要 3 个赋值操作,而插入排序只需要 1 个
在这里插入图片描述

代码(附详细注释)

public void insertSort(int[] nums) {
    //默认第一个元素是已排序的,所以从索引为1的位置开始循环
    for (int i = 1; i < nums.length; i++) {
        //temp用来存储:未排序区间的第一个值(需要找地方插入的值)
        //因为后续移动过程 这个值会被覆盖
        int temp = nums[i];
        //j是已排序区间末尾的指针,为了寻找插入点
        int j = i-1;
        //已排序区间从后至前,依次比较
        while (j >= 0){
            //如果 j处元素大于需要插入的值
            if (nums[j] > temp) {
                //j处元素,向后移动一格
                nums[j+1] = nums[j];
            } else {
                //j处元素 不大于需要插入的值 就证明需要插入的值(temp)找到了归宿
                break;
            }
            //j回退一格
            j--;
        }
        //temp找到了归宿,插入j的后面,j+1的位置
        nums[j+1] = temp;
    }
}

性能分析

  • 插入排序是原地排序

  • 插入排序是稳定的排序

  • 时间复杂度最好O(n),最坏O(n^2)


选择排序

核心思想

选择排序是每次会从未排序的区间中找到最小的元素,将其放到头部

选择与插入的对比

  • 插入排序是拿未排序区间的值,去已排序区间遍历,直到找到属于他的位置(初始情况第一个元素是已排序区间,作为参照物)
  • 选择排序是在未排序区间里做文章,先找到最小元素的位置,然后放在头部,每次确定一个最小值

代码(附详细注释)

public void selectSort(int[] nums) {
    for (int i = 0; i < nums.length - 1; i++) {
    	//用来记录最小值的索引位置,默认值为i
        int minIndex = i; 
        //遍历 i+1 ~ length 的值,找到其中最小值的位置
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[j] < nums[minIndex]) {
                minIndex = j; 
            }
        }
        // 交换当前索引 i 和最小值索引 minIndex 两处的值
        if (i != minIndex) {
            int temp = nums[i];
            nums[i] = nums[minIndex];
            nums[minIndex] = temp;
        }
        // 执行完一次循环,当前索引 i 处的值为最小值,直到循环结束即可完成排序
    }
}

性能分析

  • 选择排序是原地排序

  • 选择排序不是稳定的排序

  • 时间复杂度最好最坏都是O(n^2)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Garritsen___

希望帮助的大家

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值