冒泡排序
冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。
一次冒泡排序的过程
六次冒泡排序的全过程
改进冒泡排序过程
当某次冒泡操作已经没有数据交换时,说明已经达到完全有序,不用再继续执行后续的冒泡操作。我这里还有另外一个例子,这里面给 6 个元素排序,只需要 4 次冒泡操作就可以了。
实现代码
func BubbleSort(array []int) []int {
//当要排序的数组里的元素少于或等于1个时,说明不用再排序
if len(array) <= 1 {
return array
}
temp := 0
for i := 0; i < len(array); i++ {
//isFlag是提前退出循环的标志位,某一次遍历发现没有数据交换,说明数组中已然有序
isFlag := false
for j := 1; j < len(array)-i; j++ {
if array[j] < array[j-1] {
temp = array[j-1]
array[j-1] = array[j]
array[j] = temp
isFlag = true
}
}
if !isFlag {
break
}
}
return array
}
func main() {
array := []int{39, 2, 5, 23, 54, 12, 78, 34, 45, 40}
array = BubbleSort(array)
for i, v := range array {
fmt.Printf("下标为%d的值为%d", i, v)
fmt.Println()
}
}
总结
- 冒泡的过程只涉及相邻数据的交换操作,只需要常量级的临时空间,所以它的空间复杂度为 O(1),是一个原地排序算法。
- 在冒泡排序中,只有交换才可以改变两个元素的前后顺序。为了保证冒泡排序算法的稳定性,当有相邻的两个元素大小相等的时候,我们不做交换,相同大小的数据在排序前后不会改变顺序,所以冒泡排序是稳定的排序算法。
- 最好情况下,要排序的数据已经是有序的了,我们只需要进行一次冒泡操作,就可以结束了,所以最好情况时间复杂度是 O(n)。而最坏的情况是,要排序的数据刚好是倒序排列的,我们需要进行 n 次冒泡操作,所以最坏情况时间复杂度为 O(n2)。