最近在学习算法导论,课程上讲了两种排序算法,分别是插入排序法和合并选择法
下面用GO语言实现,不过实现得不够简洁,这位作者的更好http://austingwalters.com/merge-sort-in-go-golang/
package sort
//InsertionSort 插入排序 n^2
func InsertionSort(arr []int) {
if len(arr) < 2 {
return
}
for j := 1; j < len(arr); j++ {
key := arr[j]
i := j - 1
for i >= 0 && arr[i] > key {
arr[i+1] = arr[i]
i--
}
arr[i+1] = key
}
}
//MergeSort 合并选择算法 nlgn
func MergeSort(arr []int) (sorted []int) {
n := len(arr)
if n == 1 {
return arr
}
sorted1 := MergeSort(arr[0 : n/2])
sorted2 := MergeSort(arr[n/2:])
return mergeSortedList(sorted1,sorted2)
}
func mergeSortedList(arr1, arr2 []int) []int {
len1 := len(arr1)
len2 := len(arr2)
var pointer1, pointer2 int
result := make([]int, len1+len2)
var index = 0
for (pointer1 < len1) && (pointer2 < len2) {
if arr1[pointer1] < arr2[pointer2] {
result[index] = arr1[pointer1]
pointer1++
} else {
result[index] = arr2[pointer2]
pointer2++
}
index++
}
//arr1或者arr2被提取完时
if pointer1 == len1 {
for i := pointer2; i < len2; i++ {
result[index] = arr2[i]
index++
}
} else {
for i := pointer1; i < len1; i++ {
result[index] = arr1[i]
index++
}
}
return result
}
觉得实现的不够简洁,修改了一下,采用添加哨兵的方式来减少程序中的判断
//这个版本性能更好,加入了哨兵牌,就可以不用做过顶的检查
func mergeSortedList2(arr1, arr2 []int) []int {
var p1, p2 int
length := len(arr1) + len(arr2)
result := make([]int, length)
var arr1M, arr2M []int
arr1M = append(arr1M, arr1...)
arr1M = append(arr1M, math.MaxInt64)
arr2M = append(arr2M, arr2...)
arr2M = append(arr2M, math.MaxInt64)
for index := 0; index < length; index++ {
if arr1M[p1] < arr2M[p2] {
result[index] = arr1M[p1]
p1++
} else {
result[index] = arr2M[p2]
p2++
}
}
return result
}
下面是测试代码
package sort
import(
"testing"
"fmt"
)
func TestSort(t *testing.T) {
fmt.Println("开始测试")
arr := []int{10, 7, 1, 5, 11, 3, 100, 250, 110, 13, 0, -88, -7}
InsertionSort(arr)
fmt.Println(arr)
}
func TestMergeSort(t *testing.T) {
fmt.Println("开始测试")
arr := []int{10, 7, 1, 5, 11, 3, 100, 250, 110, 13, 0, -88, -7}
result := MergeSort(arr)
fmt.Println(result)
}