回答編集履歴

1

コードの追加

2019/07/17 00:14

投稿

kazuma-s
kazuma-s

スコア8224

test CHANGED
@@ -23,3 +23,107 @@
23
23
  再帰呼出しで、ローカルに大きな配列を確保し続けると、
24
24
 
25
25
  スタックオーバーフローが起きやすくなりますよ。
26
+
27
+ ### 追記
28
+
29
+ 最初に1回 msort の中で必要な領域を確保しておけば、
30
+
31
+ 再帰呼出しの merge_sort ではそれを使うだけのコードを書いてみました。
32
+
33
+ ```C
34
+
35
+ #include <stdio.h> // printf, putchar
36
+
37
+ #include <stdlib.h> // malloc, free
38
+
39
+
40
+
41
+ #define N 8
42
+
43
+
44
+
45
+ void show(int x[], int n)
46
+
47
+ {
48
+
49
+ for (int i = 0; i < n; i++) printf(" %d", x[i]);
50
+
51
+ putchar('\n');
52
+
53
+ }
54
+
55
+
56
+
57
+ void merge(int x[], int m, int y[], int n, int t[])
58
+
59
+ {
60
+
61
+ int i = 0, j = 0, k = 0;
62
+
63
+ while (j < m && k < n) t[i++] = (x[j] < y[k]) ? x[j++] : y[k++];
64
+
65
+ while (j < m) t[i++] = x[j++];
66
+
67
+ while (k < n) t[i++] = y[k++];
68
+
69
+ }
70
+
71
+
72
+
73
+ void merge_sort(int x[], int n, int t[])
74
+
75
+ {
76
+
77
+ if (n < 2) return;
78
+
79
+ int n1 = n / 2, n2 = n - n1;
80
+
81
+ merge_sort(x, n1, t);
82
+
83
+ merge_sort(x + n1, n2, t);
84
+
85
+ merge(x, n1, x + n1, n2, t);
86
+
87
+ for (int i = 0; i < n; i++) x[i] = t[i];
88
+
89
+ }
90
+
91
+
92
+
93
+ void msort(int x[], int n, int y[])
94
+
95
+ {
96
+
97
+ int *t = malloc(sizeof(int) * n * 2);
98
+
99
+ if (!t) { puts("out of memory"); return; }
100
+
101
+ for (int i = 0; i < n; i++) t[i] = x[i];
102
+
103
+ merge_sort(t, n, t + n);
104
+
105
+ for (int i = 0; i < n; i++) y[i] = t[i];
106
+
107
+ free(t);
108
+
109
+ }
110
+
111
+
112
+
113
+ int main()
114
+
115
+ {
116
+
117
+ int x[N] = { 18, 37, 21, 14, 7, 12, 19, 6 }, y[N];
118
+
119
+ show(x, N);
120
+
121
+ msort(x, N, y);
122
+
123
+ show(y, N);
124
+
125
+ }
126
+
127
+
128
+
129
+ ```