@@ -72,7 +72,11 @@ func _insertionSort<C>(
72
72
}
73
73
}
74
74
75
- /// Sorts the elements at indices `a`, `b`, and `c`. Stable.
75
+ /// Sorts the elements at `elements[a]`, `elements[b]`, and `elements[c]`.
76
+ /// Stable.
77
+ ///
78
+ /// The indices passed as `a`, `b`, and `c` do not need to be consecutive, but
79
+ /// must be in strict increasing order.
76
80
///
77
81
/// - Precondition: `a < b && b < c`
78
82
/// - Postcondition: `elements[a] <= elements[b] && elements[b] <= elements[c]`
@@ -86,8 +90,25 @@ func _sort3<C>(
86
90
C : MutableCollection & RandomAccessCollection
87
91
${"" if p else ", C.Iterator.Element : Comparable"}
88
92
{
89
- // Possible starting states for elements at a, b, and c:
90
- // 123, 132, 213, 231, 312, 321, 112, 121, 211, 122, 212, 221, 111
93
+ // There are thirteen possible permutations for the original ordering of
94
+ // the elements at indices `a`, `b`, and `c`. The comments in the code below
95
+ // show the relative ordering of the three elements using a three-digit
96
+ // number as shorthand for the position and comparative relationship of
97
+ // each element. For example, "312" indicates that the element at `a` is the
98
+ // largest of the three, the element at `b` is the smallest, and the element
99
+ // at `c` is the median. This hypothetical input array has a 312 ordering for
100
+ // `a`, `b`, and `c`:
101
+ //
102
+ // [ 7, 4, 3, 9, 2, 0, 3, 7, 6, 5 ]
103
+ // ^ ^ ^
104
+ // a b c
105
+ //
106
+ // - If each of the three elements is distinct, they could be ordered as any
107
+ // of the permutations of 1, 2, and 3: 123, 132, 213, 231, 312, or 321.
108
+ // - If two elements are equivalent and one is distinct, they could be
109
+ // ordered as any permutation of 1, 1, and 2 or 1, 2, and 2: 112, 121, 211,
110
+ // 122, 212, or 221.
111
+ // - If all three elements are equivalent, they are already in order: 111.
91
112
92
113
switch (${cmp("elements[b]", "elements[a]", p)},
93
114
${cmp("elements[c]", "elements[b]", p)}) {
@@ -96,24 +117,29 @@ func _sort3<C>(
96
117
break
97
118
98
119
case (true, true):
99
- // 1 swap: 321->123
120
+ // 1 swap: 321
121
+ // swap(a, c): 312->123
100
122
swap(&elements[a], &elements[c])
101
123
102
124
case (true, false):
103
125
// 1 swap: 213, 212 --- 2 swaps: 312, 211
104
- // 213->123, 212->122 --- 312->132, 211->121
126
+ // swap(a, b): 213->123, 212->122, 312->132, 211->121
105
127
swap(&elements[a], &elements[b])
128
+
106
129
if ${cmp("elements[c]", "elements[b]", p)} {
107
- // 132->123, 121->112
130
+ // 132 (started as 312), 121 (started as 211)
131
+ // swap(b, c): 132->123, 121->112
108
132
swap(&elements[b], &elements[c])
109
133
}
110
134
111
135
case (false, true):
112
136
// 1 swap: 132, 121 --- 2 swaps: 231, 221
113
- // 132->123, 121->112 --- 231->213, 221->212
137
+ // swap(b, c): 132->123, 121->112, 231->213, 221->212
114
138
swap(&elements[b], &elements[c])
139
+
115
140
if ${cmp("elements[b]", "elements[a]", p)} {
116
- // 213->123, 212->122
141
+ // 213 (started as 231), 212 (started as 221)
142
+ // swap(a, b): 213->123, 212->122
117
143
swap(&elements[a], &elements[b])
118
144
}
119
145
}
0 commit comments