6分钟彻底搞定冒泡排序

冒泡排序原理

冒泡排序(Bubble Sort),重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

冒泡排序思路

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。最后的元素应该会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个(即已经排好的元素)。
  • 重复上面的步骤,直到没有任何一对数字需要比较。

冒泡排序步骤

依次比较相邻的元素。如果第一个比第二个大,就交换他们两个。
(1)第一轮比较:比较第1和第2个元素,将小的数放前面,将大的数放后面。
(2)比较第2和第3个元素,将小的数放前面,将大的数放后面。

(3)比较第n - 1和第n个元素,将小的数放前面,将大的数放后面。此时第n个元素是序列最大的元素,已经将该元素移至序列尾,已经把此元素位置确定下来。不参与下一轮比较。
(4)第二轮比较:比较第1和第2个元素,将小的数放前面,将大的数放后面。
(5)比较第2和第3个元素,将小的数放前面,将大的数放后面。

(6)比较第n - 2和第n - 1个元素,将小的数放前面,将大的数放后面。此时第n - 1个元素是序列第二大的元素,已经把此元素位置确定下来。不参与下一轮比较。

(7)第n - 1轮比较:比较第1和第2个元素,将小的数放前面,将大的数放后面。此时序列已经排完序。

冒泡排序实例

假设待排序的序列为{10,34,2,52,28}。
1

第一轮比较:
首先比较第一和第二个元素,第一个元素10小于第二个元素34,符合排序规则,继续进行下一次比较。
2

比较第二和第三个元素,第二个元素34大于第三个元素2,交换两个元素。
3

交换后两个元素符号排序规则,继续进行下一次比较。
4

比较第三和第四个元素,第三个元素34小于第四个元素52,符合排序规则,继续进行下一次比较。
5

比较第四和第五个元素,第四个元素52大于第五个元素28,交换两个元素。
6

第一轮比较结束,元素52是此序列最大元素,已经将其移至序列最右边,其位置已经确定,不再参与下一轮比较。
7

第二轮比较:
首先比较第一和第二个元素,第一个元素10大于第二个元素2,交换两个元素。
8

交换后两个元素符号排序规则,继续进行下一次比较。
9

比较第二和第三个元素,第二个元素10小于第三个元素34,符合排序规则,继续进行下一次比较。
10

比较第三和第四个元素,第三个元素34大于第四个元素28,交换两个元素。
11

第二轮比较结束,元素34是此子序列最大元素,已经将其移至此子序列最右边,其位置已经确定,不再参与下一轮比较。
12

第三轮比较:
首先比较第一和第二个元素,第一个元素2小于第二个元素10,符合排序规则,继续进行下一次比较。
13

比较第二和第三个元素,第二个元素10小于第三个元素28,符合排序规则。
14

第三轮比较结束,元素28是此子序列最大元素,已经将其移至此子序列最右边,其位置已经确定,不再参与下一轮比较。
15

第四轮比较:
首先比较第一和第二个元素,第一个元素2小于第二个元素10,符合排序规则。
16

第四轮比较结束,元素10是此子序列最大元素,已经将其移至此子序列最右边。整个序列已经排序完成。
17

冒泡排序分析

(1)n个数字要排完序,一共要进行n - 1轮排序,每i趟的排序次数为(n - i)次。
(2)冒泡排序优点:每进行一趟排序,就会少比较一次,因为每进行一轮排序都会找出此轮序列中的最大值,下一轮不再对此最大元素排序。
(3)时间复杂度:如果序列已经排完序,只需要走一轮即可。这种情况是冒泡排序的最好情况,时间复杂度为 O ( n ) O(n) O(n)。如果序列是逆序的,则需要进行n - 1轮排序。每轮排序要进行n - i次比较(1 ≤ i ≤ n-1)。这种情况是冒泡排序的最坏情况,时间复杂度为 O ( n 2 ) O(n^{2}) O(n2)。因此,冒泡排序总的平均时间复杂度为 O ( n 2 ) O(n^{2}) O(n2)
(4)稳定性:冒泡排序就是把小的元素往前调或者把大的元素往后调。排序过程中相同元素的前后顺序并没有改变,冒泡排序是一种稳定排序算法。

冒泡排序代码实现(Java版本)

public void bubbleSort(int[] array) {
    // 如果序列为空 或者 序列长度为1 直接返回即可
    if (array == null || array.length < 2)
        return;
    // 遍历序列
    for(int i = 0 ;i < array.length - 1; ++i) {
        // 第i轮比较
        for(int j = 0 ;j < array.length - i - 1; ++j) {
            // 比较序列第 j 个元素和第 j+1 个元素
            // 如果 第j个元素大于第j+1个元素,就互换两个元素
            if(array[j] > array[j + 1]) {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值