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

C++で実装する鳩の巣ソート(Pigeonhole Sort)の仕組みとサンプルプログラム

鳩の巣ソート(Pigeonhole Sort)とは

鳩の巣ソートは、要素同士の比較を一切行わない「非比較ソート」手法の一つです。ソート対象の要素数(n)と、キーとなりうる値の範囲(N)がほぼ同じである場合に特に適しており、計算量は O(n + N) で動作します。別名「カウントソート(Count Sort)」とも呼ばれています。

このソートを実行するには、まず「穴(ピジョンホール)」を用意します。必要な穴の数は、数値の範囲によって決定されます。各要素を対応する穴に挿入していき、最後に穴から取り出して配列へ格納することで、ソート済みの並び順が完成します。

Input: arr[]={7,4,2,6,3,1,5}
Output: 1 2 3 4 5 6 7

アルゴリズムの手順

  • 配列内の最小値(min)と最大値(max)を求めます。その後、範囲を「max − min + 1」として計算します。

  • 求めた範囲と同じサイズの、初期状態が空の配列(ピジョンホール用の配列)を用意します。

  • 元の配列の各要素を走査し、それぞれ対応する穴へ格納します。要素 arr[i] は、インデックス「arr[i] − min」の位置にある穴に入ります。

  • 最後に、ピジョンホール用の配列を先頭から順番に走査し、空でない穴からすべての要素を元の配列へ書き戻します。

C++による実装例

#include <iostream>
using namespace std;
#define MAX 7
void pigeonhole_sort(int, int, int *);
int main() {
    int i, min, max;
    int a[]={7,4,2,6,3,1,5};
    min = a[0];
    max = a[0];
    for (i = 1; i < MAX; i++) {
        if (a[i] < min) {
            min = a[i];
        }
        if (a[i] > max) {
            max = a[i];
        }
    }
    pigeonhole_sort(min, max, a);
    for (i = 0; i < MAX; i++) {
        cout<< a[i]<<"\t";
    }
}
void pigeonhole_sort(int mi, int ma, int * a) {
    int size, count = 0, i;
    int *current;
    current = a;
    size = ma - mi + 1;
    int holes[size];
    for (i = 0; i < size; i++) {
        holes[i] = 0;
    }
    for (i = 0; i < size; i++, current++) {
        holes[*current-mi] += 1;
    }
    for (count = 0, current = &a[0]; count < size; count++) {
        while (holes[count]--> 0) {
            *current++ = count + mi;
        }
    }
}

出力結果

1 2 3 4 5 6 7

まとめ

鳩の巣ソートは、データの値の範囲が狭く、要素数とほぼ一致している場合に非常に効率的なソートアルゴリズムです。時間計算量は O(n + N)、補助記憶域として範囲分の配列が必要となるため、空間計算量は O(N) となります。比較ベースのソート(クイックソートやマージソートなど)とは異なるアプローチなので、用途に応じて使い分けることが重要です。

  1. 配列の全要素を乗算するC++プログラムの解説

    整数型の要素を持つ配列が与えられたとき、配列内のすべての要素を掛け合わせ、その積を表示することを考えます。本記事では、この問題をC++(C言語スタイルのコード)で解く方法を、アプローチ、アルゴリズム、サンプルコード、実行結果まで順を追って解説します。 例 入力: arr[]={1,2,3,4,5,6,7} 出力: 1 x 2 x 3 x 4 x 5 x 6 x 7 = 5040 入力: arr[]={3, 4, 6, 2, 7, 8, 4} 出力: 3 x 4 x 6 x 2 x 7 x 8 x 4 = 32256 解き方のアプローチ この問題は、累積用の一時変数を用意し、配列の要素を先頭

  2. C++で8進数を10進数に変換するプログラムの書き方

    8進数が入力として与えられたとき、それを10進数に変換するのが本記事のテーマです。 コンピュータ上の10進数は基数10で表現されます。一方、8進数は基数8で表現され、使用できる数字は0〜7に限られます。これに対して10進数では、0〜9までの任意の数字を使用することができます。 8進数から10進数への変換手順 右から左へ向かって剰余演算により各桁を取り出し、0から始まるべき乗を掛けます。指数は「桁数 − 1」に達するまで1ずつ増加させます。 8進数を変換するため、べき乗の基数は8となります(8進数の基数が8であるため)。 入力された数値の各桁に基数とべき乗を掛け、その結果を記録します。 すべて