LoginSignup
1
0

More than 5 years have passed since last update.

JavaScript シェルソート

Last updated at Posted at 2017-02-06

シェルソート

シェルソートは挿入ソートを改良されてつくられたソートアルゴリズムです。

間隔を空けて挿入ソートを行い、その間隔をだんだんと狭めていきます。
「ドナルド・シェル」さんにちなんでシェルソートと呼ばれます。

基本アイデア
・少ないデータであればソートは速く行える
→データをグループ分けして、少ないデータ量にする
・大雑把でも順番に並んでいる部分が多いと挿入ソートは高速にできる
→間隔を空けてソートすることで「小さい値は一気に前へ、大きい値は一気に後ろへ移動する」効果を利用

手順
前提 未整列のデータを用意する。
1 配列の一定間隔ごとに離れた値をひとつのグループとして考える。間隔の変数(step)を用意して、その範囲を狭めていく。
2 各グループに挿入ソートを行う。挿入ソートは先頭の値を「整列済み」、二つ目以降を「未整列」として処理を開始する。
3 step個のグループができているので、「整列済み」はstep個あることになる。
4 間隔(step)を半分にしていっても、step個以降が「未整列」なおで、ここから挿入ソートを行う。
5 取り出した値をどこに挿入すれば良いのか各グループの後ろからstep間隔で前に向かってみていく。
6 間隔(step)が1つになると全体が1つのグループになる。
7 この状態で挿入ソートを行うと全データに挿入ソートが行われたことになり、整列済みになる。

ポイント
・「グループ分けの間隔を半分にしていく繰り返し」を行う
・その中で「整列していない部分から、挿入する値を順番に1つずつ取り出す」繰り返し
・その中で「取り出した値を、整列した部分のどこに挿入するかを判定する」繰り返し
シェルソートは三重の繰り返しで出来ている

script.js
//未整列のデータ
var a = [10,3,1,9,7,6,8,2,4,5];

//「グループ分けの間隔を半分にしていく繰り返し」
for(var step = parseInt(a.length/2); step > 0; step = parseInt(step/2)){

    //間隔をあけて挿入ソートを行う
    //挿入する値を1つずつ取り出す繰り返し
    for(var i = step; i < a.length; i++){
        //挿入する値を一時的に保存する
        var tmp = a[i];
        //取り出した位置から前に向かって比較するfor文
        for(var j = i; j >= step; j -= step){
            if(a[j-step]>tmp){
                //挿入する値が小さい場合、その値をstep幅だけ後ろへずらす
                a[j] = a[j - step];
            }else{
                //挿入する値が小さくなければ、処理を止める
                break;
            }
        }
        //ずらす処理が終わったところに「挿入する値」をいれる
        a[j] = tmp;
        }
    }

//ソート後の値を表示
console.log(a);

補足
間隔(step)の最初は「配列の個数を2で割った値」で、それを2で割りながら繰り返す。
割り切れなかった場合を想定して、parseInt()で整数化する

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