OLD | NEW |
| (Empty) |
1 part of dart._internal; | |
2 class Sort {static const int _INSERTION_SORT_THRESHOLD = 32; | |
3 static void sort(List a, int compare(a, b)) { | |
4 _doSort(a, 0, a.length - 1, compare); | |
5 } | |
6 static void sortRange(List a, int from, int to, int compare(a, b)) { | |
7 if ((from < 0) || (to > a.length) || (to < from)) { | |
8 throw "OutOfRange"; | |
9 } | |
10 _doSort(a, from, to - 1, compare); | |
11 } | |
12 static void _doSort(List a, int left, int right, int compare(a, b)) { | |
13 if ((right - left) <= _INSERTION_SORT_THRESHOLD) { | |
14 _insertionSort(a, left, right, compare); | |
15 } | |
16 else { | |
17 _dualPivotQuicksort(a, left, right, compare); | |
18 } | |
19 } | |
20 static void _insertionSort(List a, int left, int right, int compare(a, b)) { | |
21 for (int i = left + 1; i <= right; i++) { | |
22 var el = a[i]; | |
23 int j = i; | |
24 while ((j > left) && (compare(a[j - 1], el) > 0)) { | |
25 a[j] = a[j - 1]; | |
26 j--; | |
27 } | |
28 a[j] = el; | |
29 } | |
30 } | |
31 static void _dualPivotQuicksort(List a, int left, int right, int compare(a, b))
{ | |
32 assert (right - left > _INSERTION_SORT_THRESHOLD); int sixth = (right - left +
1) ~/ 6; | |
33 int index1 = left + sixth; | |
34 int index5 = right - sixth; | |
35 int index3 = (left + right) ~/ 2; | |
36 int index2 = index3 - sixth; | |
37 int index4 = index3 + sixth; | |
38 var el1 = a[index1]; | |
39 var el2 = a[index2]; | |
40 var el3 = a[index3]; | |
41 var el4 = a[index4]; | |
42 var el5 = a[index5]; | |
43 if (compare(el1, el2) > 0) { | |
44 var t = el1; | |
45 el1 = el2; | |
46 el2 = t; | |
47 } | |
48 if (compare(el4, el5) > 0) { | |
49 var t = el4; | |
50 el4 = el5; | |
51 el5 = t; | |
52 } | |
53 if (compare(el1, el3) > 0) { | |
54 var t = el1; | |
55 el1 = el3; | |
56 el3 = t; | |
57 } | |
58 if (compare(el2, el3) > 0) { | |
59 var t = el2; | |
60 el2 = el3; | |
61 el3 = t; | |
62 } | |
63 if (compare(el1, el4) > 0) { | |
64 var t = el1; | |
65 el1 = el4; | |
66 el4 = t; | |
67 } | |
68 if (compare(el3, el4) > 0) { | |
69 var t = el3; | |
70 el3 = el4; | |
71 el4 = t; | |
72 } | |
73 if (compare(el2, el5) > 0) { | |
74 var t = el2; | |
75 el2 = el5; | |
76 el5 = t; | |
77 } | |
78 if (compare(el2, el3) > 0) { | |
79 var t = el2; | |
80 el2 = el3; | |
81 el3 = t; | |
82 } | |
83 if (compare(el4, el5) > 0) { | |
84 var t = el4; | |
85 el4 = el5; | |
86 el5 = t; | |
87 } | |
88 var pivot1 = el2; | |
89 var pivot2 = el4; | |
90 a[index1] = el1; | |
91 a[index3] = el3; | |
92 a[index5] = el5; | |
93 a[index2] = a[left]; | |
94 a[index4] = a[right]; | |
95 int less = left + 1; | |
96 int great = right - 1; | |
97 bool pivots_are_equal = (compare(pivot1, pivot2) == 0); | |
98 if (pivots_are_equal) { | |
99 var pivot = pivot1; | |
100 for (int k = less; k <= great; k++) { | |
101 var ak = a[k]; | |
102 int comp = compare(ak, pivot); | |
103 if (comp == 0) continue; | |
104 if (comp < 0) { | |
105 if (k != less) { | |
106 a[k] = a[less]; | |
107 a[less] = ak; | |
108 } | |
109 less++; | |
110 } | |
111 else { | |
112 while (true) { | |
113 comp = compare(a[great], pivot); | |
114 if (comp > 0) { | |
115 great--; | |
116 continue; | |
117 } | |
118 else if (comp < 0) { | |
119 a[k] = a[less]; | |
120 a[less++] = a[great]; | |
121 a[great--] = ak; | |
122 break; | |
123 } | |
124 else { | |
125 a[k] = a[great]; | |
126 a[great--] = ak; | |
127 break; | |
128 } | |
129 } | |
130 } | |
131 } | |
132 } | |
133 else { | |
134 for (int k = less; k <= great; k++) { | |
135 var ak = a[k]; | |
136 int comp_pivot1 = compare(ak, pivot1); | |
137 if (comp_pivot1 < 0) { | |
138 if (k != less) { | |
139 a[k] = a[less]; | |
140 a[less] = ak; | |
141 } | |
142 less++; | |
143 } | |
144 else { | |
145 int comp_pivot2 = compare(ak, pivot2); | |
146 if (comp_pivot2 > 0) { | |
147 while (true) { | |
148 int comp = compare(a[great], pivot2); | |
149 if (comp > 0) { | |
150 great--; | |
151 if (great < k) break; | |
152 continue; | |
153 } | |
154 else { | |
155 comp = compare(a[great], pivot1); | |
156 if (comp < 0) { | |
157 a[k] = a[less]; | |
158 a[less++] = a[great]; | |
159 a[great--] = ak; | |
160 } | |
161 else { | |
162 a[k] = a[great]; | |
163 a[great--] = ak; | |
164 } | |
165 break; | |
166 } | |
167 } | |
168 } | |
169 } | |
170 } | |
171 } | |
172 a[left] = a[less - 1]; | |
173 a[less - 1] = pivot1; | |
174 a[right] = a[great + 1]; | |
175 a[great + 1] = pivot2; | |
176 _doSort(a, left, less - 2, compare); | |
177 _doSort(a, great + 2, right, compare); | |
178 if (pivots_are_equal) { | |
179 return;} | |
180 if (less < index1 && great > index5) { | |
181 while (compare(a[less], pivot1) == 0) { | |
182 less++; | |
183 } | |
184 while (compare(a[great], pivot2) == 0) { | |
185 great--; | |
186 } | |
187 for (int k = less; k <= great; k++) { | |
188 var ak = a[k]; | |
189 int comp_pivot1 = compare(ak, pivot1); | |
190 if (comp_pivot1 == 0) { | |
191 if (k != less) { | |
192 a[k] = a[less]; | |
193 a[less] = ak; | |
194 } | |
195 less++; | |
196 } | |
197 else { | |
198 int comp_pivot2 = compare(ak, pivot2); | |
199 if (comp_pivot2 == 0) { | |
200 while (true) { | |
201 int comp = compare(a[great], pivot2); | |
202 if (comp == 0) { | |
203 great--; | |
204 if (great < k) break; | |
205 continue; | |
206 } | |
207 else { | |
208 comp = compare(a[great], pivot1); | |
209 if (comp < 0) { | |
210 a[k] = a[less]; | |
211 a[less++] = a[great]; | |
212 a[great--] = ak; | |
213 } | |
214 else { | |
215 a[k] = a[great]; | |
216 a[great--] = ak; | |
217 } | |
218 break; | |
219 } | |
220 } | |
221 } | |
222 } | |
223 } | |
224 _doSort(a, less, great, compare); | |
225 } | |
226 else { | |
227 _doSort(a, less, great, compare); | |
228 } | |
229 } | |
230 } | |
OLD | NEW |