質問への追記を求めるのも面倒なので、エスパーして教科書の実装を完成させた上で回答します。
3と7はどの段階で入れ替えを免れたのでしょうか。
1回目に通る Arrange
では想像されている通り、一度 A[0]
と A[9]
を交換しています。しかし、A[0]
が Pivot
よりも小さくなければ A[0]
を再び A[R]
と交換しようとしています。同様に A[9]
が Pivot
よりも大きくなければ A[9]
を A[L]
と再び交換しようとしています。
つまり、Arrange
の while
ループの1回目では、3
と 7
を交換しますが、その直後、2回目のループで 3
と 7
を元に戻しています。
その結果、まるで 3
と 7
の交換がなかったように QuickSort
の1回目が終了しています。説明はこれでよいでしょうか。
c
1#include <stdio.h>
2#include <stdlib.h>
3
4#define true 1
5#define false 0
6
7void debug(int A[], int Min, int Max) {
8 int i;
9 for (i = 0; i < 10; ++i) {
10 if (i > 0) printf(", ");
11 printf("%d", A[i]);
12 }
13 puts("");
14}
15
16void Arrange(int A[], int Min, int Max, int Pivot, int *Ret) {
17 int L, R, Tmp;
18
19 L = Min;
20 R = Max;
21 while (L <= R) {
22 Tmp = A[L];
23 A[L] = A[R];
24 A[R] = Tmp;
25 while (A[L] < Pivot) {
26 L += 1;
27 }
28 while (A[R] >= Pivot) {
29 R -= 1;
30 }
31 }
32 *Ret = L;
33}
34
35void FindPivot(int A[], int Min, int Max, int *Ret) {
36 int Pivot, K, Found;
37 Pivot = A[Min];
38 K = Min + 1;
39 *Ret = -1;
40 Found = false;
41
42 while (K <= Max && !Found) {
43 if (A[K] == Pivot) {
44 K += 1;
45 }
46 else {
47 Found = true;
48
49 if (A[K] > Pivot) {
50 *Ret = K;
51 }
52 else {
53 *Ret = Min;
54 }
55 }
56 }
57}
58
59void QuickSort(int A[], int Min, int Max) {
60 int Pivot, J, K, L;
61 debug(A, Min, Max);
62
63 FindPivot(A, Min, Max, &J);
64 if (J > -1) {
65 Pivot = A[J];
66 Arrange(A, Min, Max, Pivot, &K);
67 L = K - 1;
68 QuickSort(A, Min, L);
69 QuickSort(A, K, Max);
70 }
71}
72
73int main() {
74 int A[10] = {3,5,8,4,0,6,9,1,2,7};
75 QuickSort(A, 0, 9);
76 return 0;
77}