Go 语言气泡排序
最后修改于 2025年3月8日
本教程将探讨 Go 语言中的气泡排序算法。我们将演示如何对数字和文本数据进行升序和降序排序,并将其与快速排序进行基准测试。
一个 算法 是一个定义良好的步骤序列,旨在高效地解决问题或完成任务。在编程中,算法是计算逻辑的支柱。
排序 是指将数据集合组织成特定的序列,例如升序(从小到大)或降序(从大到小)。它是从数据库到用户界面的许多应用程序中的一项关键操作。
常用排序算法
以下是一些广泛认可的排序算法:
- 气泡排序
- 快速排序
- 归并排序
- 插入排序
- 选择排序
气泡排序算法
气泡排序是一种简单的排序方法,它遍历列表,比较相邻的项,如果顺序错误则交换它们。它之所以得名,是因为较大的元素会像气泡一样“冒”到末尾。
这个过程会重复进行,直到不再需要交换为止,这表示列表已排序。虽然简单,但由于其二次时间复杂度,它对于大型数据集来说不是最快的。
气泡排序示例
下面是一个用于数字的 Go 语言气泡排序实现。
package main
import "fmt"
func bubbleSort(arr []int) {
n := len(arr)
for i := 0; i < n; 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]
}
}
}
}
func main() {
nums := []int{64, 34, 25, 12, 22, 11, 90}
bubbleSort(nums)
fmt.Println("Sorted array:", nums)
}
此代码定义了一个 bubbleSort 函数,该函数对整数切片进行升序排序。外循环运行 n 次,其中 n 是切片的长度。
内循环比较相邻的元素,如果左边的元素大于右边的元素,则交换它们。执行后,数组将从小到大排序。
$ go run bubble_sort.go Sorted array: [11 12 22 25 34 64 90]
对文本数据进行排序
气泡排序也可以处理字符串。这里有一个对文本进行升序和降序排序的例子。
package main
import "fmt"
func bubbleSort(arr []string, reverse bool) {
n := len(arr)
for i := 0; i < n; i++ {
for j := 0; j < n-i-1; j++ {
if (!reverse && arr[j] > arr[j+1]) || (reverse && arr[j] < arr[j+1]) {
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
}
func main() {
words := []string{"banana", "apple", "cherry", "date"}
bubbleSort(words, false)
fmt.Println("Ascending order:", words)
bubbleSort(words, true)
fmt.Println("Descending order:", words)
}
bubbleSort 函数现在接受一个 reverse 布尔值来切换排序方向。对于升序,如果左边的字符串按字母顺序大于右边的字符串,则进行交换。
对于降序,如果左边的字符串小于右边的字符串,则进行交换。这种灵活性使其适用于 Go 程序中对名称、标签或其他文本数据进行排序。
$ go run bubble_sort_text.go Ascending order: [apple banana cherry date] Descending order: [date cherry banana apple]
比较气泡排序与快速排序
气泡排序的简单性是有代价的——它对于大型数据集来说很慢,时间复杂度为 O(n²)。快速排序的平均复杂度为 O(n log n),速度要快得多。
下面的示例使用大型随机数据集对这两种算法进行了基准测试,以突出它们在 Go 语言中的性能差异。
package main
import (
"fmt"
"math/rand"
"time"
)
func bubbleSort(arr []int) {
n := len(arr)
for i := 0; i < n; 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]
}
}
}
}
func quickSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}
pivot := arr[len(arr)/2]
left := []int{}
middle := []int{}
right := []int{}
for _, x := range arr {
if x < pivot {
left = append(left, x)
} else if x == pivot {
middle = append(middle, x)
} else {
right = append(right, x)
}
}
left = quickSort(left)
right = quickSort(right)
return append(append(left, middle...), right...)
}
func main() {
rand.Seed(time.Now().UnixNano())
data := make([]int, 1000)
for i := range data {
data[i] = rand.Intn(1000)
}
bubbleData := make([]int, len(data))
copy(bubbleData, data)
start := time.Now()
bubbleSort(bubbleData)
bubbleTime := time.Since(start)
quickData := make([]int, len(data))
copy(quickData, data)
start = time.Now()
quickSort(quickData)
quickTime := time.Since(start)
fmt.Printf("Bubble Sort time: %.6f seconds\n", bubbleTime.Seconds())
fmt.Printf("Quick Sort time: %.6f seconds\n", quickTime.Seconds())
}
此代码生成 1000 个随机整数并计时这两种排序方法。bubbleSort 函数会就地修改切片,而 quickSort 则使用递归返回一个新的排序后的切片。
快速排序围绕枢轴对数据进行分区,递归地对子列表进行排序,从而使其更有效。基准测试通常显示气泡排序花费的时间要长得多——通常是 10 倍或更多。
了解这些差异有助于开发人员为他们的需求选择正确的算法,平衡实际 Go 应用程序中的简单性与性能。
来源
本教程介绍了 Go 语言中的气泡排序,包括数字和文本的示例,以及与快速排序的性能比较。