冒泡排序

87 阅读3分钟

冒泡排序

冒泡排序核心思想: 从头开始,不断比较相邻的两个元素,如果前者比后者大,就交换位置

算法步骤

  • 比较相邻元素。如果第一个比第二个大,就交换它们
  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对
  • 这步做完后,最后的元素会是最大的数
  • 针对所有的元素重复以上的步骤,除了已经是最大数的最后一个
  • 持续每次对越来越少(每次重复都会少一个最大数)的元素重复上面的步骤,直到没有任何一对数字需要比较

举例

为了方便理解,我们初始化一个数组


第一轮

第一轮将比较4次,目的是将当前数组中最大值移到最右边

比较是否交换
比较5和35>3交换数组变为 [3,5,8,4,2]
比较5和85<8不交换数组不变 [3,5,8,4,2]
比较8和48>4交换数组变为 [3,5,4,8,2]
比较8和28>2交换数组变为 [3,5,4,2,8]

此时,最大元素8已经到达最右边


第二轮

第二轮,只对前面为排序的4个元素[3,5,4,2]重复第一轮过程

比较是否交换
比较3和53<5不交换数组不变[3,5,4,2,8]
比较5和45>4交换数组变为[3,4,5,2,8]
比较5和25>2交换数组变为[3,4,2,5,8]

本轮结束后,数组为 [3, 4, 2, 5, 8]。次大元素 5 也到达了它的正确位置。


第三轮

对前面为排序的3个元素[3,4,2]重复此过程

比较是否交换
比较3和43<4不交换数组不变[3,4,2,5,8]
比较4和24>2交换数组变为[3,2,4,5,8]

本轮结束后,数组为 [3, 2, 4, 5, 8]。元素 4 到达了它的正确位置。


第四轮

对前面未排序的2个元素 [3, 2] 重复此过程。

比较是否交换
比较3和23>2交换数组变为[2,3,4,5,8]

本轮结束后,数组为 [2, 3, 4, 5, 8]

此时,所有元素都已在正确位置,排序完成


基础实现

package mian
​
import "fmt"
​
func bubbleSort(arr []int) []int{
    n := len(arr)
    
    for i := 0;i < n-1; i++ {
        for j := 0; j < n-i-1;j++{
            //如果当前元素大于下一个元素,则交换
            if arr[j] > arr[j+1]{
                arr[j],arr[j+1] = arr[j+1],arr[j]
            }
        }
    }
    return arr
}

冒泡排序的优化

我们发现,如果某轮冒泡没有执行交换,说明数组已经完成排序,可以直接返回结果,所以可以增加一个标志flag来监控这种情况,一旦出现就返回

package mian
​
import "fmt"func bubbleSort(arr []int) []int{
    n := len(arr)
    
    for i := 0;i < n-1; i++ {
        flag := false
        for j := 0; j < n-i-1;j++{
            //如果当前元素大于下一个元素,则交换
            if arr[j] > arr[j+1]{
                arr[j],arr[j+1] = arr[j+1],arr[j]
                flag = true
            }
        }
        if flag == false {
            break
        }
    }
    return arr
}