Goに慣れるためとアルゴリズムの復習の為に週1ぐらいで更新していきます。アルゴリズムクイックリファレンス 第2版を読んで各種アルゴリズムをGoで実装して行きます。
前回: Goでのアルゴリズムクイックリファレンス第2版(バケツソート)
今回はマージソート
基本的なアルゴリズムは、以下。(wikipediaより)
1. データ列を分割する(通常、等分する)
2. 各々をソートする
3. 二つのソートされたデータ列をマージする
package main
import (
	"fmt"
	"math/rand"
)
func mergeSort(a *[]int, tmp *[]int, start int, end int) {
	m := (end + start) / 2
	if end <= start {
		return
	}
	mergeSort(a, tmp, start, m)
	mergeSort(a, tmp, m+1, end)
	merge(a, tmp, start, m, end)
}
func merge(a *[]int, tmp *[]int, start int, m int, end int) {
	var start_i, end_i int
	for start_i = m + 1; start_i > start; start_i-- {
		(*tmp)[start_i-1] = (*a)[start_i-1]
	}
	for end_i = m; end_i < end; end_i++ {
		(*tmp)[end+m-end_i] = (*a)[end_i+1]
	}
	for i := start; i <= end; i++ {
		if (*tmp)[end_i] < (*tmp)[start_i] {
			(*a)[i] = (*tmp)[end_i]
			end_i--
		} else {
			(*a)[i] = (*tmp)[start_i]
			start_i++
		}
	}
}
func main() {
	var ary, tmp []int
	size := 30
	for i := 0; i < size; i++ {
		ary = append(ary, rand.Intn(size-1))
		tmp = append(tmp, 0)
	}
	fmt.Println(ary)
	mergeSort(&ary, &tmp, 0, len(ary)-1)
	fmt.Println(ary)
}
今回はしょうも無いところで色々はまって、考え違いしてるのかと思って色々参考にさせていただきました。再帰じゃないバージョンのマージソートも考察されているようで、これもあとでもう一度トライしたいです。
- http://d.hatena.ne.jp/kankinkon/20120202/1328138584
- http://konbu13.hatenablog.com/entry/2014/02/11/195731
あと、途中で見つけたこの本結構良さそうなので後で購入したいです。
次回は逐次探索の予定です。