C言語によるマージソートの実装
サンプルプログラム
ここでは実際に、C言語によるマージソートの実装を見てみることにします。処理は、配列を再帰的に半分に分け、前半、後半をそれぞれソートをお行い。その結果をマージしていく方法をとります。
前半、後半のソート結果をマージする際には、それぞれの先頭要素から、大きいものを取得し、取得した側は、一つ先に進め、また同様の比較を行い…ということを繰り返して、最終的にマージした行列をえる仕組みになっています。
この際、前半、後半の結果はそれぞれ一つの行列tmpに入れることにします。前半は、startからmiddleまで順に、後半は、middle+1からendまで逆に入れます。こうすることにより、余計な処理やメモリの無駄をなくすようにしています。
サンプルプログラム
以上の考え方を実装すると、以下のプログラムのようになります。入力して実行してみてください。
listex7-merge:main.c#include <stdio.h> #include <stdlib.h> #define MAX_LENGTH 8 void merge_sort(int*,int,int); void showData(int*,int); void main() { int array[MAX_LENGTH] = { 55 , 13 , 3 , 45 , 74, 87, 46, 30 }; showData(array,MAX_LENGTH); merge_sort(array,0,MAX_LENGTH-1); } void merge_sort(int* pArray,int start,int end){ // 作業用の配列(再帰呼び出しをするため、staticで定義する) static int tmp[MAX_LENGTH]; // 作業用のデータ int middle,i,j,k; if(start >= end){ return; } // startとendの中間地点を分割点とする middle = (start + end) / 2; // 前半部分を再帰的に整列 merge_sort(pArray,start,middle); // 後半部分を再帰的に整列 merge_sort(pArray,middle + 1,end); k = 0; // 仮想領域のデータをマージしながらコピーする。 for(i = start; i <= middle; i++){ tmp[k] = pArray[i]; k++; } for(j = end; j >= middle + 1 ; j--){ tmp[k] = pArray[j]; k++; } // 末端からデータを取得して、マージしていく。 i = 0; j = end - start; for(k = start; k <= end ; k++){ if(tmp[i] >= tmp[j]){ pArray[k] = tmp[i]; i++; }else{ pArray[k] = tmp[j]; j--; } } // 結果を出力 showData(pArray,MAX_LENGTH); } // 配列の表示 void showData(int* array,int length){ int i; for(i = 0; i < length; i++){ printf("%d ",array[i]); } printf("\n"); }
55 13 3 45 74 87 46 30
55 13 3 45 74 87 46 30
55 13 45 3 74 87 46 30
55 45 13 3 74 87 46 30
55 45 13 3 87 74 46 30
55 45 13 3 87 74 46 30
55 45 13 3 87 74 46 30
87 74 55 46 45 30 13 3
55 13 3 45 74 87 46 30
55 13 45 3 74 87 46 30
55 45 13 3 74 87 46 30
55 45 13 3 87 74 46 30
55 45 13 3 87 74 46 30
55 45 13 3 87 74 46 30
87 74 55 46 45 30 13 3