说明
归并排序是建立在归并操作上的一种有效的排序。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
逻辑
分:将一个无序数列分解为有序序列,既将一个无序数列分解为一个个单个元素的数列。
治:将两个有序数列合并成一个有序数列。
分治完成后,即得到一个完整的有序数列。
代码
package arithmetic
import (
"math"
)
//InterfaceSort 排序接口
type InterfaceSort interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}
//InterfaceSortMerge 归并排序接口
type InterfaceSortMerge interface {
InterfaceSort
GetElement(i int) interface{}
SetElement(element interface{}, i int)
}
//SortMerge 归并排序
func SortMerge(slice InterfaceSortMerge) {
tmpSlice := make([]interface{}, slice.Len(), slice.Len())
divideAndConquer(slice, 0, slice.Len()-1, tmpSlice)
}
func divideAndConquer(slice InterfaceSortMerge, bg int, ed int, tmpSlice []interface{}) {
if bg >= ed {
return
}
md := (bg + ed) / 2
divideAndConquer(slice, bg, md, tmpSlice)
divideAndConquer(slice, md+1, ed, tmpSlice)
conquer(slice, bg, md, ed, tmpSlice)
}
func conquer(slice InterfaceSortMerge, bg int, md int, ed int, tmpSlice []interface{}) {
var l = bg
var r = md + 1
var i = 0
for l <= md && r <= ed {
if slice.Less(l, r) {
tmpSlice[i] = slice.GetElement(l)
l++
i++
} else {
tmpSlice[i] = slice.GetElement(r)
r++
i++
}
}
for l <= md {
tmpSlice[i] = slice.GetElement(l)
l++
i++
}
for r <= ed {
tmpSlice[i] = slice.GetElement(r)
r++
i++
}
i = 0
for bg <= ed {
slice.SetElement(tmpSlice[i], bg)
i++
bg++
}
}
代码说明
面向对象实现,结构体实现相关接口即可调用该函数。
排序结果通过参数返回。
divideAndConquer 递归调用,将数列分治。
conquer 为治程序,将两个数列合并。
测试代码
package main
import (
"AZframework/arithmetic"
"fmt"
)
//IntSlice []int
type IntSlice []int
func (s IntSlice) Len() int { return len(s) }
func (s IntSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s IntSlice) Less(i, j int) bool { return s[i] < s[j] }
//GetElement 归并接口
func (s IntSlice) GetElement(i int) interface{} { return s[i] }
//SetElement 归并接口
func (s IntSlice) SetElement(element interface{}, i int) { s[i] = element.(int) }
func main() {
sliceC = IntSlice{5, 5, 4, 3, 2, 1, 1}
arithmetic.SortMerge(sliceC)
fmt.Printf("SortMerge slice = %v \n", sliceC)
}
日志输出
SortMerge slice = [1 1 2 3 4 5 5]
网友评论