LoginSignup
0
2

More than 5 years have passed since last update.

Goでのアルゴリズムクイックリファレンス第2版(4.3 分割ベースのソート)

Last updated at Posted at 2017-05-14

Goに慣れるためとアルゴリズムの復習の為に週1ぐらいで更新していきます。アルゴリズムクイックリファレンス 第2版を読んで各種アルゴリズムをGoで実装して行きます。

前回: Goでのアルゴリズムクイックリファレンス第2版(4.2 選択ソート)

今回はヒープソートです。

  • リストの並べ替えを二分ヒープ木を用いて行うソートのアルゴリズム
  • 計算量は O(n log n)
  • 安定ソートではない
  • アルゴリズム
    • 未整列のリストから要素を取り出し、順にヒープに追加する。すべての要素を追加するまで繰り返し。
    • ルート(最大値または最小値)を取り出し、整列済みリストに追加する。すべての要素を取り出すまで繰り返し。

package main

import (
    "fmt"
    "math/rand"
)

func sort(a *[]int) {
    buildHeap(a)
    n := len(*a)
    for i := n - 1; i >= 0; i-- {
        (*a)[0], (*a)[i] = (*a)[i], (*a)[0]
        heapify(a, 0, i)
    }
}

func buildHeap(a *[]int) {
    n := len(*a)
    for i := n/2 - 1; i >= 0; i-- {
        heapify(a, i, n)
    }
}

func heapify(a *[]int, idx int, max int) {
    largest := idx
    left := 2*idx + 1
    right := 2*idx + 2

    if left < max && (*a)[left] > (*a)[idx] {
        largest = left
    }

    if right < max && (*a)[right] > (*a)[largest] {
        largest = right
    }

    if largest != idx {
        (*a)[idx], (*a)[largest] = (*a)[largest], (*a)[idx]
        heapify(a, largest, max)
    }
}

func main() {
    var ary []int
    size := 30
    for i := 0; i < size; i++ {
        ary = append(ary, rand.Intn(size-1))
    }
    fmt.Println(ary)
    sort(&ary)
    fmt.Println(ary)
}

次回はクイックソートの予定です。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2