見出し画像

ちょっとアルゴニズム - Shell Sort(Swift)

Insertion Sort(挿入ソート)の進化版です。

1  ある間隔をあけた数字に対して比較します。
2  必要であれば入れ替えます。
3  比較した数字の間隔を小さくします。

1,2,3の繰り返しで、間隔がなくなれば終了です。

参考コードです。

func shellSort(arr: inout [Int]) -> [Int] {
  guard arr.count > 0 else { return arr }
  var gap = arr.count / 2
  while gap > 0 {
      for i in 0 ..< arr.count {
          var j = i + gap
          while j >= gap && j < arr.count {
              guard arr[j] < arr[j - gap] else { break }
              arr.swapAt(j, j - gap)
              j -= gap
          }
      }
      gap /= 2
  }
  return arr
}

"arr.swapAt()"を使って数値の入換えをしているところです。

次にinsertionSortと組み合わせてあるコードです。

上記サイトを実行したところエラーが出たため少し修正させてもらいました。

insertionSort()


func insertionSort( list: inout [Int], start: Int, gap: Int) {
   for i in stride(from:start + gap ,to: list.count, by: gap) {
   let currentValue = list[i]
   var pos = i
   while pos >= gap && list[pos - gap] > currentValue {
     list[pos] = list[pos - gap]
     pos -= gap
   }
   list[pos] = currentValue
 }
}
for i in stride(from:start + gap ,to: list.count, by: gap)

で間隔(gap)をあけた数字を取得してリストの並び替えを行います。

shellSort()

func shellSort(_ list: inout [Int]) {
   var sublistCount = list.count / 2
   while sublistCount > 0 {
       for pos in 0..<sublistCount {
           insertionSort(list: &list, start: pos, gap: sublistCount)
       }
       sublistCount = sublistCount / 2
   }
}
var sublistCount = list.count / 2

で配列を分ける間隔を決めます。この場合配列の半分のインデックスを取得しています。

あとはinsertionSort()で順番を入換えて順番にします。

間隔を減らしていき、間隔がなくなったところで終わりとなります。

このサイトわかりやすいです。


この記事が気に入ったらサポートをしてみませんか?