冒泡排序
算法概述
冒泡排序的主要过程是:对于一个数组,从头到尾依次比较相邻的两个元素,如果前后两个元素存在逆序,则交换这两个元素的位置。n 个元素的数组,需要进行 n-1 轮比较,每一轮比较都会确定一个元素的最终位置。
算法实现
// 基础版冒泡排序,每一轮比较后,最大的元素放在最后
func BubbleSortBasic(arr []int) {
n := len(arr)
// 外层循环控制比较轮数
for i := 0; i < n-1; i++ {
// 内层循环确保一个元素的最终位置, arr[n-i-1, n) 是已经有序的.
for j := 0; j < n-i-1; j++ {
if arr[j] > arr[j+1] {
// 交换 arr[j] 和 arr[j+1]
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
}
// 优化版冒泡排序
func BubbleSortOptimized(arr []int) {
n := len(arr)
// 外层循环控制比较轮数
for i := 0; i < n-1; i++ {
// 内层循环确保一个元素的最终位置, arr[n-i-1, n) 是已经有序的.
// 优化:如果某一轮比较没有发生交换,则说明数组已经有序,直接退出
isSorted := true
for j := 0; j < n-i-1; j++ {
if arr[j] > arr[j+1] {
// 交换 arr[j] 和 arr[j+1]
arr[j], arr[j+1] = arr[j+1], arr[j]
isSorted = false
}
}
if isSorted {
break
}
}
}
// 最极版冒泡排序
func BubbleSortUltimate(arr []int) {
n := len(arr)
// 外层循环控制比较轮数
for i := 0; i < n-1; {
lastSwappedIndex := 0
// 内层循环确保一个元素的最终位置, arr[n-i-1, n) 是已经有序的.
for j := 0; j < n-i-1; j++ {
if arr[j] > arr[j+1] {
arr[j+1], arr[j] = arr[j], arr[j+1]
// 最近一个确定了位置元素的序号
lastSwappedIndex = j + 1
}
}
// 已经有多少元素确定了位置
i = n - lastSwappedIndex
}
}
// 另一种方式的冒泡排序, 每轮循环后,最小的元素放在前面
func BubbleSortReverse(arr []int) {
n := len(arr)
// 外层循环控制比较轮数
for i := 0; i < n-1; {
lastSwappedIndex := n - 1
// 内层循环确保一个元素的最终位置, arr[0, i) 是已经有序的.
for j := n - 1; j > i; j-- {
if arr[j] > arr[j+1] {
arr[j-1], arr[j] = arr[j], arr[j-1]
// 最近一个确定了位置元素的序号
lastSwappedIndex = j - 1
}
}
// 已经有多少元素确定了位置
i = lastSwappedIndex + 1
}
}