归并排序算法 Go

说明

归并排序是建立在归并操作上的一种有效的排序。该算法是采用分治法(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]

你可能感兴趣的:(归并排序算法 Go)