カウントソートの実装

カウントソートを実装で学ぶ。比較なしソート、要素カウント、累積和計算で線形時間効率化を実現するアルゴリズムの数学的考え方を解説します。

Read in: en
カウントソートの実装

カウントソートとは

ソートアルゴリズムの中でも比較を使わずにソートする変わった?アルゴリズム。

比較せずに要素をカウントすることでソートができる。

カウントしてソートすることができるというのは不思議!と思ったので調べてみた。

前提

累積和について知っておく必要がある。

cf. qiita.com - 累積和とは(超初心者用)

実装

ソースコードは以下。

count_sort

package main

import "fmt"

func countSort(s []int, maxVal int) []int {
	count := make([]int, maxVal+1)

	// カウント
	for _, num := range s {
		count[num]++
	}

	// 累積和計算
	// ex. [1, 2, 3, 4, 5] → [1, 3, 6, 10, 15]
	for i := 1; i <= maxVal; i++ {
		count[i] += count[i-1]
	}

	sorted := make([]int, len(s))

	// 元の配列を末尾から走査し、要素をソート結果に配置
	for i := len(s) - 1; i >= 0; i-- {
		num := s[i]
		count[num]--
		sorted[count[num]] = num
	}

	return sorted
}

func main() {
	s := []int{5, 3, 2, 1, 2, 3, 4}
	maxVal := 5
	r := countSort(s, maxVal)
	fmt.Println(r)
}
// 出力
[1 2 2 3 3 4 5]

処理の流れとしては、

  1. 配列の要素はインデックスとして配列内の要素の出現回数をカウント
  2. 累積和を計算
  3. 配列末尾から走査してソート結果を得る

直感的ではなく何というかすごく数学的な感じがする。

参考

Tags: カウントソート
Share: 𝕏 Post Facebook Hatena
✏️ View source / Discuss on GitHub
☕ サポート

このブログを応援していただける方は、以下からサポートをお願いします。いただいたサポートはブログ運営・技術研鑽に活用します。


関連記事