Go语言冒泡排序实现

冒泡排序

    现在有一堆乱序的数,比如:  5 9 1 6 8 14 6 49 25 4 6 3 。
第一轮迭代:从第一个数开始,依次比较相邻的两个数,如果前面一个数比后面一个数大,那
么交换位置,直到处理到最后一个数,最后的这个数是最大的。
第二轮迭代:因为最后一个数已经是最大了,现在重复第一轮迭代的操作,但是只处理到倒数
第二个数。
第三轮迭代:因为最后一个数已经是最大了,最后第二个数是次大的,现在重复第一轮迭代的
操作,但是只处理到倒数第三个数。
第N轮迭代:….
经过交换,最后的结果为:  1 3 4 5 6 6 6 8 9 14 25 49 ,我们可以看到已经排好序了。
因为小的元素会慢慢地浮到顶端,很像碳酸饮料的汽泡,会冒上去,所以这就是冒泡排序取名
的来源。
个简单例子,冒泡排序一个 4 个元素的数列:  4 2 9 1
第一轮开始: 4 2 9 1 从第一个数开始,42 大,交换 42
第一轮: {2 4} 9 1 接着 49 小,不交换
第一轮: 2 {4 9} 1 接着 91 大,交换 91
第一轮: 2 4 {1 9} 已经到底,结束
第一轮结果: 2 4 1 [9]
第二轮开始:2 4 1 [9] 从第一个数开始,24 小,不交换
第二轮: {2 4} 1 [9] 接着 41 大,交换 41
第二轮: 2 {1 4} [9] 已经到底,结束
第二轮结果: 2 1 [4 9]
第三轮开始:2 1 [4 9] 从第一个数开始,21 大,交换 21
第三轮: (1 2} [4 9] 已经到底,结束
第三轮结果: 1 [2 4 9]
结果: [1 2 4 9]

当数列的元素数量为 N ,冒泡排序有两种循环,需要比较的次数为:

第一次比较的次数为: N-1 次
第二次比较的次数为: N-2 次,因为排除了最后的元素
第三次比较的次数为: N-3 次,因为排除了后两个元素
...
第某次比较的次数为: 1
比较次数:  1 + 2 + 3 + ... + (N-1) = (N^2 - N)/2 ,是一个平方级别的时间复杂度,
我们可以记为:  O(n^2) 。
交换次数:如果数列在有序的状态下进行冒泡排序,也就是最好情况下,那么交换次数为0,而
如果完全乱序,最坏情况下那么交换的次数和比较的次数一样多。
冒泡排序交换和比较的次数相加是一个和  N 有关的平方数,所以冒泡排序的最好和最差时
间复杂度都是:  O(n^2) 。
我们可以改进最好的时间复杂度,使得冒泡排序最好情况的时间复杂度是  O(n) ,请看下
面的算法实现。
冒泡排序算法是稳定的,因为如果两个相邻元素相等,是不会交换的,保证了稳定性的要求。

实现代码

package main

import "fmt"

func BubbleSort(list []int) {
   n := len(list)
   // 在一轮中有没有交换过
   didSwap := false
   for i := n - 1; i > 0; i-- {
      for j := 0; j < i; j++ {
         //如果前面的数比后面的大,那么交换
         if list[j] > list[j+1] {
            list[j], list[j+1] = list[j+1], list[j]
            didSwap = true
         }
      }
   }
   if !didSwap {
      return
   }
}
func main() {
   list := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3}
   BubbleSort(list)
   fmt.Println(list)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值