LoginSignup
2
0

More than 3 years have passed since last update.

Scalaで各種ソートアルゴリズムを実装する

Last updated at Posted at 2020-05-05

これは GW Advent Calendar 2020 俺GW頑張った の6日目の記事です。
前日の記事は Fediverseにいます さんの いろいろした です。
翌日の記事は しそのは とうふ さんの 結果何かやったかと言われたら微妙 です。

はじめに

ソートアルゴリズムの復習とScalaの学習を兼ねて、各種ソートアルゴリズムをScalaで実装してみる。
ソースは nhiguchi/sort-samples にアップした。

基本trait

trait Sorter {
  def sort(seq: Seq[Int]): Seq[Int]
}

各種ソートアルゴリズム

挿入ソート

object InsertionSorter extends Sorter {
  override def sort(seq: Seq[Int]): Seq[Int] = {
    seq.foldLeft(Seq.empty[Int]) { (seq, e) =>
      val index = seq.indexWhere(_ > e)
      if (index == -1) {
        seq :+ e
      } else {
        seq.take(index) :+ e :++ seq.drop(index)
      }
    }
  }
}

マージソート

object MergeSorter extends Sorter {
  override def sort(seq: Seq[Int]): Seq[Int] = {
    def _sort(leftSeq: Seq[Int], rightSeq: Seq[Int]): Seq[Int] = {
      (leftSeq, rightSeq) match {
        case (left, Nil)  => left
        case (Nil, right) => right
        case (leftHead :: leftTail, rightHead :: rightTail) =>
          if (leftHead < rightHead) leftHead +: _sort(leftTail, rightSeq)
          else rightHead +: _sort(leftSeq, rightTail)
      }
    }
    val pivot = seq.size / 2
    if (pivot == 0) seq
    else {
      val split = seq.splitAt(pivot)
      _sort(sort(split._1), sort(split._2))
    }
  }
}

クイックソート

object QuickSorter extends Sorter {
  override def sort(seq: Seq[Int]): Seq[Int] = {
    if (seq.size <= 1) seq
    else {
      val pivot = seq(seq.size / 2)
      sort(seq.filter(_ < pivot)) ++
        seq.filter(_ == pivot) ++
        sort(seq.filter(pivot < _))
    }
  }
}

まとめ

Scalaは高レイヤ処理が得意だが、関数型言語は低レイヤ処理にも強いことを改めて感じた。
これ以上複雑なソートになると実装が大変だが、気が向いたら残りのソートも実装してみたい。

参考サイト

2
0
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
2
0