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

反復マージソートをC言語で実装する方法|サンプルコードと実行結果を解説

マージソート(Merge Sort)は、分割統治法(Divide and Conquer)に基づく代表的な整列アルゴリズムの一つです。時間計算量はO(n log n)と非常に効率的で、まず配列を同じ大きさの半分に分割し、その後決められた手順で結合(マージ)していくことで、整列済みの配列を作り上げます。

反復マージソートとは

反復マージソートでは、要素を半分ずつに分割していく処理に再帰的なアプローチを採用し、分割された部分配列を整列済みの状態で結合して戻す処理に反復的なアプローチを使用します。

反復マージソートのCプログラム

以下は、マージソートをC言語で記述したサンプルプログラムです。merge()関数が隣接する2つの部分配列を1つの整列済み配列へ結合し、iterativeMergeSort()関数が配列の中央位置を求めながら再帰的に呼び出しを行うことで、全体のソートを制御しています。

コード例

#include<stdlib.h>
#include<stdio.h>
void merge(int arr[], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l + 1;
    int n2 = r - m;
    int L[n1], R[n2];
    for (i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1+ j];
    i = 0, j = 0, k = l;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}
void iterativeMergeSort(int arr[], int l, int r) {
    if (l < r){
        int mid = l+(r-l)/2;
        iterativeMergeSort(arr, l, mid);
        iterativeMergeSort(arr, mid+1, r);
        merge(arr, l, mid, r);
    }
}
int main(){
    int arr[] = {12, 11, 13, 5, 6, 7};
    int size = sizeof(arr)/sizeof(arr[0]);
    printf("\t\t ITERATIVE MERGE SORT \n");
    printf("Unsorted Array : \t");
    for (int i=0; i < size; i++)
        printf("%d ",arr[i]);
    iterativeMergeSort(arr, 0, size - 1);
    printf("\nSorted array : \t");
    for (int i=0; i < size; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

実行結果

ITERATIVE MERGE SORT
Unsorted Array : 12 11 13 5 6 7
Sorted array : 5 6 7 11 12 13

プログラムを実行すると、まず未整列の配列「12 11 13 5 6 7」が出力されます。その後、反復マージソートが適用され、昇順に並べ替えられた配列「5 6 7 11 12 13」が出力されます。

まとめ

マージソートは、最悪・平均・最良のいずれのケースでもO(n log n)の時間計算量を維持できる安定ソートである点が大きな特徴です。一方で、結合時には一時的な作業用配列が必要となるため、空間計算量はO(n)となる点に注意が必要です。大規模データの整列や連結リスト、外部ソートなどへの応用も可能な、信頼性の高いアルゴリズムといえます。

  1. Pythonで実装する反復型(非再帰)クイックソートのプログラム

    この記事では、次の問題に対する解決策をPythonのコードとともに詳しく解説します。 問題の概要 問題文: 与えられた配列を、クイックソートの考え方を利用して反復的(非再帰的)な手法でソートします。 通常、クイックソートは再帰呼び出しによって実装されることが多いですが、ここでは明示的にスタックを使用することで、再帰なしに同じアルゴリズムを実現します。まず配列をパーティション(分割)し、その各部分を個別にソートしていくことで、最終的に全体がソートされた配列を得ます。 アルゴリズムの流れ ソート対象の範囲(開始インデックス l と終了インデックス h)をスタックにプッシュする。 スタックが空にな

  2. 【Python】再帰を使わない反復型(ボトムアップ)マージソートの実装方法を解説

    この記事では、反復処理(イテレーション)のみでマージソートを実装する方法について解説します。再帰呼び出しを使わずに、whileループだけで配列を整列させる「ボトムアップ方式」のアプローチを見ていきましょう。 問題文 問題: 与えられた配列を、反復処理によるマージソートの考え方を用いて昇順に並べ替えてください。 例として、次の整数配列を扱います。 a = [2, 5, 3, 8, 6, 5, 4, 7] 反復マージソートの考え方 通常のマージソートは再帰を使って配列を分割しますが、反復版では最初から要素数1の部分配列として捉え、隣接する部分配列同士を統合(マージ)しながらサイズを倍々に増やしてい