問題
- マージソートを作成せよ。配列Aをソートせよ。(教科書 p. 52の例。問3.4 p.55) 再帰的なプログラムを作成すること
#define N 10 int A[N]={42,33,78,19,46,63,25,11,54,17}; とする
A: 42 33 78 19 46 63 25 11 54 17 ← ソート前出力 A: 11 17 19 25 33 42 46 54 63 78 ← ソート後出力マージソートの様子をプリントするようにして、実行を確認するとよい。 たとえば、下の実行例では、leftからrightまでがマージソートの対象で、leftからhalf, half+1からrightまでがマージされている様子をプリントしている。配列の添え字が0から始まることに注意
A: 42 33 78 19 46 63 25 11 54 17 Merge:left= 0, half= 0, right= 1 42 33 78 19 46 63 25 11 54 17 42 33 ** ** ** ** ** ** ** ** <- A[0]と、A[1]をマージする Merge:left= 0, half= 1, right= 2 33 42 78 19 46 63 25 11 54 17 <- マージ結果 33 42 78 ** ** ** ** ** ** ** <- 次は A[0] からA[1]と、A[2] Merge:left= 3, half= 3, right= 4 33 42 78 19 46 63 25 11 54 17 ** ** ** 19 46 ** ** ** ** ** Merge:left= 0, half= 2, right= 4 33 42 78 19 46 63 25 11 54 17 33 42 78 19 46 ** ** ** ** ** <- A[0]からA[2]と、A[3]からA[4] Merge:left= 5, half= 5, right= 6 19 33 42 46 78 63 25 11 54 17 ** ** ** ** ** 63 25 ** ** ** Merge:left= 5, half= 6, right= 7 19 33 42 46 78 25 63 11 54 17 ** ** ** ** ** 25 63 11 ** ** Merge:left= 8, half= 8, right= 9 19 33 42 46 78 11 25 63 54 17 ** ** ** ** ** ** ** ** 54 17 Merge:left= 5, half= 7, right= 9 19 33 42 46 78 11 25 63 17 54 ** ** ** ** ** 11 25 63 17 54 <- A[5]からA[7]と、A[8]からA[9] Merge:left= 0, half= 4, right= 9 19 33 42 46 78 11 17 25 54 63 19 33 42 46 78 11 17 25 54 63 <- 最後はA[0]からA[4]と、A[5]からA[9] A: 11 17 19 25 33 42 46 54 63 78
解答例
[プログラムテンプレート(未完)]
#include <stdio.h> #define N 10 /* 大域変数 */ int A[N]={42,33,78,19,46,63,25,11,54,17}; /* 関数宣言 変数の型と仮引数をしっかり書いた場合 */ /* int B[]は、「intの要素を格納する配列」を宣言している */ void merge(int B[], int left, int half, int right); void merge_sort(int left, int right); /* 前半 (left - half)と後半(half+1 - right) をBにマージ */ void merge(int B[], int left, int half, int right){ int i, j, k; i = left; void merge_sort(int left, int right){ int half, k; int B[N]; /* マージ用配列 */ /* 停止条件は、left==rightつまり、要素が1のとき。そのままで答え */ /* 再帰条件 */ if(left < right){ /* ほぼ真ん中 */ /* 前半をソート */ /* 後半をソート */ /* Bにマージしよう */ /* マージ結果を大域変数の配列Aに書き戻し */ for(k = ){ A[k] = } } } int main(void){ int i; /* 配列A ソート前。表示 */ printf("A:"); for(i=0; i < N; i++) { printf("%3d ",A[i]); } printf("\n"); printf("\n"); merge_sort(0, N-1); /* left=0 right=N-1までをマージソート! */ /* 配列A、ソート後 */ printf("A:"); for(i=0; i < N; i++) { printf("%3d ",A[i]); } printf("\n"); printf("\n"); return(0); }
コメント