Java实现排序算法(一)冒泡排序及其优化 (个人笔记)

冒泡排序(Bubble sorting)

就像气泡一样,小气泡往上冒变成大气泡

  1. 从头开始比较每一对相邻的元素,如果左边的元素大于右边的元素,则调换位置(一轮扫描结束后,最大的数在最后面)
  2. 忽略1中找到的最大元素,重复1,直到元素有序

这里以升序为例,降序反之即可

图像演示:

从下标1开始

在这里插入图片描述

发现左边(3)比本身(2)大,所以要调换位置

在这里插入图片描述

然后下标+1继续比较

在这里插入图片描述

发现左边(3)比本身(4)小,不处理,下标继续+1比较,直到下标为4时,发现左边大于本身于是调换位置

在这里插入图片描述

此时下标要回到一开始(也就是下标为1),第二轮就不用处理最后那个最大的元素了(也就是下标为4的最大元素)
在这里插入图片描述

第二轮最后:
在这里插入图片描述

第三轮最后:

在这里插入图片描述

第四轮:
在这里插入图片描述

此时 退出循环

代码演示

public static void BubbleSorting1(int[] ints) {
    for (int end = ints.length - 1; end > 0; end--) {//每扫描完一轮,最后一个元素都不用再扫描
        for (int start = 1; start <= end; start++) {//下标从1开始扫描比较
            if (ints[start - 1] > ints[start]) {//如果左边大于右边(本身)则交换位置
                int temp = ints[start - 1];
                ints[start - 1] = ints[start];
                ints[start] = temp;
            }
        }
    }
}
优化
优化一

如果序列有序了,我们就可以提前终止循环

什么时候序列有序呢?

如果我们一轮扫描没有发生位置的交换说明序列有序可以提前终止循环,我们可以使用打标记

public static void BubbleSorting2(int[] ints) {
        for (int end = ints.length - 1; end > 0; end--) {
            boolean flag = true;//代表是 有序
            for (int start = 1; start <= end; start++) {
                if (ints[start - 1] > ints[start]) {
                    int temp = ints[start - 1];
                    ints[start - 1] = ints[start];
                    ints[start] = temp;
                    //如果发生了位置交换 说明不是有序
                    flag = false;
                }
            }
            if (flag) break;//如果是有序 直接退出循环
        }
}

如果在大概率无序的情况下,使用这种方法效率会比第一种方法还低

优化二

如果序列尾部局部有序,可以记录下最后一次比较的位置,下一轮扫描就不用比较比这个位置还后的下标了,减少比较次数

public static void BubbleSorting3(int[] ints) {
    for (int end = ints.length - 1; end > 0; end--) {
        int lastSort = 1;
        for (int start = 1; start <= end; start++) {
            if (ints[start - 1] > ints[start]) {
                int temp = ints[start - 1];
                ints[start - 1] = ints[start];
                ints[start] = temp;
                lastSort = start;//记录这次位置交换的下标
            }
        }
        end = lastSort;
    }
}

还发现如果序列本来就有序,不发生位置交换,lastSort为1赋值给end 就正好满足了优化一的那种方法

总结
  • 时间复杂度
    • 最好:O(n) 【有序序列,外循环只执行1次时】
    • 最坏,平均:O(n^2)
  • 空间复杂度
    • O(1)
  • 稳定性
    • 稳定(如果将左边大于右边就交换位置,改为左边大于等于右边交换位置则会变的不稳定)
  • In-place
  • 最好:O(n) 【有序序列,外循环只执行1次时】
  • 最坏,平均:O(n^2)
  • 空间复杂度
    • O(1)
  • 稳定性
    • 稳定(如果将左边大于右边就交换位置,改为左边大于等于右边交换位置则会变的不稳定)
  • In-place
    • 因为冒泡排序没有依赖额外空间资源所以是原地算法

若有错,麻烦指出,感谢

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值