归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package main

import (
    "fmt"
    "math/rand"
    "time"
)

const (
    num      = 10
    rangeNum = 10
)

func main() {
    randSeed := rand.New(rand.NewSource(time.Now().Unix() + time.Now().UnixNano()))
    var buf []int
    for i := 0; i < num; i++ {
        buf = append(buf, randSeed.Intn(rangeNum))
    }
    t := time.Now()

    // 选择排序
    mergeSort(buf)
    fmt.Println(buf)
    fmt.Println(time.Since(t))
}

//归并排序
func mergeSort(buf []int) {
    tmp := make([]int, len(buf))
    merge_sort(buf, 0, len(buf)-1, tmp)
}

func merge_sort(a []int, first, last int, tmp []int) {
    if first < last {
        middle := (first + last) / 2
        merge_sort(a, first, middle, tmp)       //左半部分排好序
        merge_sort(a, middle+1, last, tmp)      //右半部分排好序
        mergeArray(a, first, middle, last, tmp) //合并左右部分
    }
}

func mergeArray(a []int, first, middle, end int, tmp []int) {
    i, m, j, n, k := first, middle, middle+1, end, 0
    for i <= m && j <= n {
        if a[i] <= a[j] {
            tmp[k] = a[i]
            k++
            i++
        } else {
            tmp[k] = a[j]
            k++
            j++
        }
    }
    for i <= m {
        tmp[k] = a[i]
        k++
        i++
    }
    for j <= n {
        tmp[k] = a[j]
        k++
        j++
    }

    for ii := 0; ii < k; ii++ {
        a[first+ii] = tmp[ii]
    }
    fmt.Printf("merge sort: buf: %v\n", a)
}

  • go run merge.go
1
2
3
4
5
6
7
8
9
10
11
12
13
midoksdeMacBook-Pro:test midoks$ go run merge.go 
merge sort: buf: [5 8 6 0 5 5 7 3 8 7]
merge sort: buf: [5 6 8 0 5 5 7 3 8 7]
merge sort: buf: [5 6 8 0 5 5 7 3 8 7]
merge sort: buf: [0 5 5 6 8 5 7 3 8 7]
merge sort: buf: [0 5 5 6 8 5 7 3 8 7]
merge sort: buf: [0 5 5 6 8 3 5 7 8 7]
merge sort: buf: [0 5 5 6 8 3 5 7 7 8]
merge sort: buf: [0 5 5 6 8 3 5 7 7 8]
merge sort: buf: [0 3 5 5 5 6 7 7 8 8]
[0 3 5 5 5 6 7 7 8 8]
73.401µs