Go:排序算法
一、冒泡排序
package main import "fmt" func BubbleSort(arr []int) { /* 思路:将大的元素一步一步"冒泡"到最后 */ l := len(arr) for i := 0; i < l-1; i++ { exchange := false for j := 0; j < l-1-i; j++ { // l-1 是因为只需要遍历到数组的倒数第二个元素,此时就可以拿这个元素和最后一个元素比较了 if arr[j] > arr[j+1] { arr[j], arr[j+1] = arr[j+1], arr[j] exchange = true } } if !exchange { return } } } func main() { arr := []int{5, 17, 1, 68, 22} fmt.Println("排序前:", arr) BubbleSort(arr) fmt.Println("排序后:", arr) }
二、选择排序
package main import "fmt" func SelectSort(arr []int) { /* 思路: 1.把第一个没有排序过的元素设置为最小值 2.遍历每个没有排序过的元素 如果元素 < 现在的最小值 将此元素设置成为新的最小值 3.经过步骤2后,如果最小值发生改变,则将最小值和第一个没有排序过的位置交换 */ l := len(arr) for i := 0; i < l-1; i++ { // l-1 是因为最后一个元素不需要比较了 /* 无序区间: 第一次:[0, l-1] 第二次:[1, l-1] ... */ minIndex := i // 记录最小值的索引 for j := i+1; j < l; j++ { // i+1 表示自己不用跟自己比 if arr[j] < arr[minIndex] { minIndex = j // 更新最小值索引 } } if i != minIndex { // i 不是最小值时,将 i 和最小值进行交换 arr[i], arr[minIndex] = arr[minIndex], arr[i] } } } func main(){ arr := []int{5, 17, 1, 68, 22} fmt.Println("排序前:", arr) SelectSort(arr) fmt.Println("排序后:", arr) }
三、插入排序
package main import "fmt" func InsertSort(arr []int) { /* 思路: 1.将第一个元素标记为已排序 2.遍历每个没有排序过的元素,将每次遍历的第一个元素用临时变量保存 因为: 第一次遍历从索引 1 开始 第二次遍历从索引 2 开始 所以: 设遍历索引为 i (从1开始),则临时变量保存的元素是 arr[i] 3.如果排序过的最后一个元素 > 临时保存的元素,则将排序过的元素向右移一格;否则,插入这个临时保存的元素 */ l := len(arr) for i := 1; i < l; i ++ { // i = [1, 2, 3... l-1] temp := arr[i] // temp用来保存未排序序列的第一个元素 prevIndex := i - 1 // 已排序序列的最后一个元素索引 for ; prevIndex >=0 && arr[prevIndex] > temp; { arr[prevIndex + 1] = arr[prevIndex] // 右移 prevIndex -= 1 // 右移过后,temp还要和有序序列的每个元素从后向前依次比较,所以 prevIndex 自减 1 } arr[prevIndex + 1] = temp // 经过上面的循环右移,直到条件不满足,则将 temp 插入索引为 prevIndex 元素的后面 } } func main() { arr := []int{5, 17, 1, 68, 22} fmt.Println("排序前:", arr) InsertSort(arr) fmt.Println("排序后:", arr) }
四、快速排序
package main import "fmt" func QuickSort(arr []int) { quickSort(arr, 0, len(arr)-1) } func quickSort(arr []int, left, right int) []int { if left < right { partitionIndex := partition(arr, left, right) quickSort(arr, left, partitionIndex-1) quickSort(arr, partitionIndex+1, right) } return arr } func partition(arr []int, left, right int) int { temp := arr[left] // 基准(pivot)元素 for ; left < right; { // 从序列右边往左边找,直到找到比基准小的元素才退出循环 for ; left < right && arr[right] >= temp; { right -= 1 } arr[left] = arr[right] // 将这个元素"左移" // 从序列左边往右边找,直到找到比基准大的元素才退出循环 for ; left < right && arr[left] <= temp; { left += 1 } arr[right] = arr[left] // 将这个元素"右移" } arr[left] = temp // 相当于将基准元素放到"中间",此时基准元素左边都是小于基准元素的元素,右边同理 return left } func main() { arr := []int{5, 17, 1, 68, 22} fmt.Println("排序前:", arr) QuickSort(arr) fmt.Println("排序后:", arr) }