C++
 Computer >> コンピューター >  >> プログラミング >> C++

シェルソートを実装するC++プログラム


シェルソート(Shell Sort)は、挿入ソートを改良した整列アルゴリズムです。通常の挿入ソートでは、要素を正しい位置に挿入するために大量のデータをまとめてシフト(移動)する必要がある場合があります。シェルソートでは、あらかじめ一定の間隔(ギャップ)ごとに離れた要素同士を比較・交換することで、大規模なシフト処理を大幅に減らすことができます。

整列は特定の間隔で行われ、各パスが終了するたびにギャップを半分に縮小していき、最終的にギャップが1になれば完全に整列された状態になります。

シェルソートの計算量

  • 時間計算量:最良ケースは O(n log n)。その他のケースでは、採用するギャップ列(間隔の選び方)に依存します。

  • 空間計算量:O(1)(追加のメモリはほとんど不要)

入力 − 未整列のリスト:23 56 97 21 35 689 854 12 47 66
出力 − 整列後の配列:12 21 23 35 47 56 66 97 689 854

アルゴリズム

shellSort(array, size)

入力:データの配列と、その要素数

出力:整列済みの配列

Begin
    gap := size / 2 から開始し、gap > 0 の間、gap を gap / 2 ずつ更新しながら繰り返す
        j := gap から size - 1 まで繰り返す
            k := j - gap から 0 まで、gap ずつ減らしながら繰り返す
                if array[k+gap] >= array[k] ならば
                    break(ループを抜ける)
                else
                    array[k + gap] と array[k] を交換する
            done
        done
    done
End

サンプルコード

#include<iostream>
using namespace std;
void swapping(int &a, int &b) {     // a と b の中身を交換する
    int temp;
    temp = a;
    a = b;
    b = temp;
}
void display(int *array, int size) {
    for(int i = 0; i<size; i++)
        cout << array[i] << " ";
    cout << endl;
}
void shellSort(int *arr, int n) {
    int gap, j, k;
    for(gap = n/2; gap > 0; gap = gap / 2) {     // 初期値 gap = n/2、
        // 以降は gap / 2 ずつ減少させる
        for(j = gap; j<n; j++) {
            for(k = j-gap; k>=0; k -= gap) {
                if(arr[k+gap] >= arr[k])
                    break;
                else
                    swapping(arr[k+gap], arr[k]);
            }
        }
    }
}
int main() {
    int n;
    cout << "Enter the number of elements: ";
    cin >> n;
    int arr[n];    // 指定された要素数で配列を作成
    cout << "Enter elements:" << endl;
    for(int i = 0; i<n; i++) {
        cin >> arr[i];
    }
    cout << "Array before Sorting: ";
    display(arr, n);
    shellSort(arr, n);
    cout << "Array after Sorting: ";
    display(arr, n);
}

実行結果

Enter the number of elements: 10
Enter elements:
23 56 97 21 35 689 854 12 47 66
Array before Sorting: 23 56 97 21 35 689 854 12 47 66
Array after Sorting: 12 21 23 35 47 56 66 97 689 854

このように、シェルソートはギャップを段階的に狭めながら整列を進めることで、挿入ソート特有の大規模なデータ移動を回避できます。特に中規模程度のデータに対して効率的に動作するため、実用的な整列手法の一つとして広く知られています。


  1. C++で基数ソート(ラディックスソート)を実装するプログラム

    基数ソート(ラディックスソート)は、非比較型のソートアルゴリズムの一つです。要素同士を直接比較するのではなく、整数キーを構成する各桁に注目し、同じ桁位置・同じ値を持つ数字どうしをグループ化しながら並べ替えを行います。 「基数」とは記数法における底のことです。私たちが普段使う10進法では基数は10であるため、10進数を基数ソートで並べ替える際には、数値を一時的に格納するための10個のバケット(ポケット)が必要になります。 基数ソートの計算量 時間計算量: O(nk) ※nは要素数、kは最大桁数 空間計算量: O(n+k) 入力 − ソート前のデータ: 802 630 20 745 52 3

  2. Pythonでシェルソートを実装するプログラムの書き方

    シェルソートとは シェルソート(Shell Sort)は、挿入ソートを改良した整列アルゴリズムです。実装する際には、リストとその長さを引数として受け取る関数を定義します。この関数では、一定の間隔(ギャップ)ごとに抽出した部分リストに対して整列を行い、間隔を徐々に狭めながら処理を繰り返します。 まず最も大きな間隔から開始し、間隔だけ離れた要素同士を比較・交換していきます。この操作を、間隔が最小値になるまで繰り返すことで、リスト全体が完全に整列されます。すべての部分リストがこの手順で並べ替えられるため、最終的にソート済みの状態になります。 なお、Pythonのリストは異なるデータ型の値(整数、浮動