冒泡排序
冒泡排序核心思想: 从头开始,不断比较相邻的两个元素,如果前者比后者大,就交换位置
算法步骤
- 比较相邻元素。如果第一个比第二个大,就交换它们
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对
- 这步做完后,最后的元素会是最大的数
- 针对所有的元素重复以上的步骤,除了已经是最大数的最后一个
- 持续每次对越来越少(每次重复都会少一个最大数)的元素重复上面的步骤,直到没有任何一对数字需要比较
举例
为了方便理解,我们初始化一个数组
第一轮
第一轮将比较4次,目的是将当前数组中最大值移到最右边
| 比较 | 是否交换 | ||
|---|---|---|---|
| 比较5和3 | 5>3 | 交换 | 数组变为 [3,5,8,4,2] |
| 比较5和8 | 5<8 | 不交换 | 数组不变 [3,5,8,4,2] |
| 比较8和4 | 8>4 | 交换 | 数组变为 [3,5,4,8,2] |
| 比较8和2 | 8>2 | 交换 | 数组变为 [3,5,4,2,8] |
此时,最大元素8已经到达最右边
第二轮
第二轮,只对前面为排序的4个元素[3,5,4,2]重复第一轮过程
| 比较 | 是否交换 | ||
|---|---|---|---|
| 比较3和5 | 3<5 | 不交换 | 数组不变[3,5,4,2,8] |
| 比较5和4 | 5>4 | 交换 | 数组变为[3,4,5,2,8] |
| 比较5和2 | 5>2 | 交换 | 数组变为[3,4,2,5,8] |
本轮结束后,数组为 [3, 4, 2, 5, 8]。次大元素 5 也到达了它的正确位置。
第三轮
对前面为排序的3个元素[3,4,2]重复此过程
| 比较 | 是否交换 | ||
|---|---|---|---|
| 比较3和4 | 3<4 | 不交换 | 数组不变[3,4,2,5,8] |
| 比较4和2 | 4>2 | 交换 | 数组变为[3,2,4,5,8] |
本轮结束后,数组为 [3, 2, 4, 5, 8]。元素 4 到达了它的正确位置。
第四轮
对前面未排序的2个元素 [3, 2] 重复此过程。
| 比较 | 是否交换 | ||
|---|---|---|---|
| 比较3和2 | 3>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
}