golang归并排序
package main
import "fmt"
func main() {
a := []int{8, 6, 5, 4, 3, 2, 1}
mergeSort(a, 0, len(a)-1)
fmt.Println(a)
}
func mergeSort(a []int, l, r int) {
if l >= r { // 必须要有=,只有一个就不用归并,递归结束条件
return
}
m := (r-l)>>1 + l
mergeSort(a, l, m)
mergeSort(a, m+1, r)
merge(a, l, m, r)
}
func merge(a []int, l, m, r int) {
t := make([]int, r-l+1)
i, j := l, m+1
k := 0
for i <= m && j <= r {
if a[i] < a[j] {
t[k] = a[i]
i++
k++
} else {
t[k] = a[j]
j++
k++
}
}
for i <= m {
t[k] = a[i]
i++
k++
}
for j <= r {
t[k] = a[j]
j++
k++
}
k = 0
for x := l; x <= r; x++ {
a[x] = t[k]
k++
}
}
output
快速排序
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
a := []int{8, 7, 6, 5, 4, 3, 2, 1}
quickSort(a, 0, len(a)-1)
fmt.Println(a)
}
func quickSort(a []int, l, r int) {
if l > r {
return
}
p := partition(a, l, r)
quickSort(a, l, p-1)
quickSort(a, p+1, r)
}
func partition(a []int, l, r int) int {
// 使用随机数作为基准,防止本来是有序数组,使排序退化为一个链表
ri := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(r-l+1) + l
a[l], a[ri] = a[ri], a[l]
v := a[l]
// a[l+1,i) a(j,r]
i, j := l+1, r
for {
for i <= r && a[i] < v {
i++
}
for j >= l+1 && a[j] > v {
j--
}
if i > j {
break
}
// 交换 i,j
a[i], a[j] = a[j], a[i]
i++
j--
}
// 交换 l,j 返回j,这是j<i,j为小于v的索引而不是i
a[l], a[j] = a[j], a[l]
return j
}
output
冒泡排序
package main
import "fmt"
func main() {
a := []int{1, 2, 3, 4, 5, 6, 7, 8}
bubbleSort(a)
fmt.Println(a)
}
func bubbleSort(a []int) {
n := len(a)
isSorted := true
for i := 0; i < n; i++ {
isSorted = true
fmt.Println("-------")
for j := 0; j < n-1-i; j++ {
if a[j] > a[j+1] {
isSorted = false
a[j], a[j+1] = a[j+1], a[j]
}
}
if isSorted {
break
}
}
}
output
选择排序
package main
import "fmt"
func main() {
a := []int{6, 5, 4, 3, 2, 1}
selectSort(a)
fmt.Println(a)
}
func selectSort(a []int) {
n := len(a)
for i := 0; i < n; i++ {
min := i
for j := i + 1; j < n; j++ {
if a[j] < a[i] {
min = j
}
}
a[i], a[min] = a[min], a[i]
}
}
output
插入排序
package main
import "fmt"
func main() {
a := []int{6, 5, 4, 3, 2, 1}
insertSort(a)
fmt.Println(a)
}
func insertSort(a []int) {
n := len(a)
for i := 1; i < n; i++ {
v := a[i]
j := i - 1
for ; j >= 0; j-- {
if v >= a[j] {
break
} else {
a[j+1] = a[j]
}
}
a[j+1] = v
}
}
output
堆排序
package main
import "fmt"
func main() {
a := []int{5, 4, 3, 2, 1}
l := len(a)
heapSort(a, l)
fmt.Println(a)
}
func heapSort(arr []int, n int) {
for i := (n - 1) / 2; i >= 0; i-- {
HeapAdjust(arr, i, n) //对序列中的每个非叶子节点执行调整算法,使之成为一个堆
}
for i := n - 1; i > 0; i-- { //从最后一个元素开始对序列进行调整,直到第一个元素
arr[0], arr[i] = arr[i], arr[0]
HeapAdjust(arr, 0, i)
}
}
func HeapAdjust(arr []int, i, n int) {
var nChild int
for ; 2*i+1 < n; i = nChild { //判断是否为叶子结点,当调整了一个,下面的都要调整
nChild = 2*i + 1
if nChild < n-1 && arr[nChild+1] > arr[nChild] {
nChild++
} //判断右结点是否存在,取大值
if arr[i] < arr[nChild] {
arr[nChild], arr[i] = arr[i], arr[nChild]
} else {
break
}
}
}