| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // TODO(ahe): Remove this file and use the shared one. | 5 // TODO(ahe): Remove this file and use the shared one. |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Dual-Pivot Quicksort algorithm. | 8 * Dual-Pivot Quicksort algorithm. |
| 9 * | 9 * |
| 10 * This class implements the dual-pivot quicksort algorithm as presented in | 10 * This class implements the dual-pivot quicksort algorithm as presented in |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 } else { | 147 } else { |
| 148 // comp > 0. | 148 // comp > 0. |
| 149 // | 149 // |
| 150 // Find the first element <= pivot in the range [k - 1, great] and | 150 // Find the first element <= pivot in the range [k - 1, great] and |
| 151 // put [:ak:] there. We know that such an element must exist: | 151 // put [:ak:] there. We know that such an element must exist: |
| 152 // When k == less, then el3 (which is equal to pivot) lies in the | 152 // When k == less, then el3 (which is equal to pivot) lies in the |
| 153 // interval. Otherwise a[k - 1] == pivot and the search stops at k-1. | 153 // interval. Otherwise a[k - 1] == pivot and the search stops at k-1. |
| 154 // Note that in the latter case invariant 2 will be violated for a | 154 // Note that in the latter case invariant 2 will be violated for a |
| 155 // short amount of time. The invariant will be restored when the | 155 // short amount of time. The invariant will be restored when the |
| 156 // pivots are put into their final positions. | 156 // pivots are put into their final positions. |
| 157 while (true) { | 157 bool done = false; |
| 158 while (!done) { |
| 158 comp = compare(a[great], pivot); | 159 comp = compare(a[great], pivot); |
| 159 if (comp > 0) { | 160 if (comp > 0) { |
| 160 great--; | 161 great--; |
| 161 // This is the only location in the while-loop where a new | 162 // This is the only location in the while-loop where a new |
| 162 // iteration is started. | 163 // iteration is started. |
| 163 // continue; | 164 // continue; |
| 164 } else if (comp < 0) { | 165 } else if (comp < 0) { |
| 165 // Triple exchange. | 166 // Triple exchange. |
| 166 a[k] = a[less]; | 167 a[k] = a[less]; |
| 167 a[less++] = a[great]; | 168 a[less++] = a[great]; |
| 168 a[great--] = ak; | 169 a[great--] = ak; |
| 169 break; | 170 done = true; |
| 170 } else { | 171 } else { |
| 171 // comp == 0; | 172 // comp == 0; |
| 172 a[k] = a[great]; | 173 a[k] = a[great]; |
| 173 a[great--] = ak; | 174 a[great--] = ak; |
| 174 // Note: if great < k then we will exit the outer loop and fix | 175 // Note: if great < k then we will exit the outer loop and fix |
| 175 // invariant 2 (which we just violated). | 176 // invariant 2 (which we just violated). |
| 176 break; | 177 done = true; |
| 177 } | 178 } |
| 178 } | 179 } |
| 179 } | 180 } |
| 180 } | 181 } |
| 181 } else { | 182 } else { |
| 182 // We partition the list into three parts: | 183 // We partition the list into three parts: |
| 183 // 1. < pivot1 | 184 // 1. < pivot1 |
| 184 // 2. >= pivot1 && <= pivot2 | 185 // 2. >= pivot1 && <= pivot2 |
| 185 // 3. > pivot2 | 186 // 3. > pivot2 |
| 186 // | 187 // |
| (...skipping 14 matching lines...) Expand all Loading... |
| 201 int comp_pivot1 = compare(ak, pivot1); | 202 int comp_pivot1 = compare(ak, pivot1); |
| 202 if (comp_pivot1 < 0) { | 203 if (comp_pivot1 < 0) { |
| 203 if (k != less) { | 204 if (k != less) { |
| 204 a[k] = a[less]; | 205 a[k] = a[less]; |
| 205 a[less] = ak; | 206 a[less] = ak; |
| 206 } | 207 } |
| 207 less++; | 208 less++; |
| 208 } else { | 209 } else { |
| 209 int comp_pivot2 = compare(ak, pivot2); | 210 int comp_pivot2 = compare(ak, pivot2); |
| 210 if (comp_pivot2 > 0) { | 211 if (comp_pivot2 > 0) { |
| 211 while (true) { | 212 bool done = false; |
| 213 while (!done) { |
| 212 int comp = compare(a[great], pivot2); | 214 int comp = compare(a[great], pivot2); |
| 213 if (comp > 0) { | 215 if (comp > 0) { |
| 214 great--; | 216 great--; |
| 215 if (great < k) break; | 217 if (great < k) done = true; |
| 216 // This is the only location inside the loop where a new | 218 // This is the only location inside the loop where a new |
| 217 // iteration is started. | 219 // iteration is started. |
| 218 // continue; | 220 // continue; |
| 219 } else { | 221 } else { |
| 220 // a[great] <= pivot2. | 222 // a[great] <= pivot2. |
| 221 comp = compare(a[great], pivot1); | 223 comp = compare(a[great], pivot1); |
| 222 if (comp < 0) { | 224 if (comp < 0) { |
| 223 // Triple exchange. | 225 // Triple exchange. |
| 224 a[k] = a[less]; | 226 a[k] = a[less]; |
| 225 a[less++] = a[great]; | 227 a[less++] = a[great]; |
| 226 a[great--] = ak; | 228 a[great--] = ak; |
| 227 } else { | 229 } else { |
| 228 // a[great] >= pivot1. | 230 // a[great] >= pivot1. |
| 229 a[k] = a[great]; | 231 a[k] = a[great]; |
| 230 a[great--] = ak; | 232 a[great--] = ak; |
| 231 } | 233 } |
| 232 break; | 234 done = true; |
| 233 } | 235 } |
| 234 } | 236 } |
| 235 } | 237 } |
| 236 } | 238 } |
| 237 } | 239 } |
| 238 } | 240 } |
| 239 | 241 |
| 240 // Move pivots into their final positions. | 242 // Move pivots into their final positions. |
| 241 // We shrunk the list from both sides (a[left] and a[right] have | 243 // We shrunk the list from both sides (a[left] and a[right] have |
| 242 // meaningless values in them) and now we move elements from the first | 244 // meaningless values in them) and now we move elements from the first |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 int comp_pivot1 = compare(ak, pivot1); | 293 int comp_pivot1 = compare(ak, pivot1); |
| 292 if (comp_pivot1 == 0) { | 294 if (comp_pivot1 == 0) { |
| 293 if (k != less) { | 295 if (k != less) { |
| 294 a[k] = a[less]; | 296 a[k] = a[less]; |
| 295 a[less] = ak; | 297 a[less] = ak; |
| 296 } | 298 } |
| 297 less++; | 299 less++; |
| 298 } else { | 300 } else { |
| 299 int comp_pivot2 = compare(ak, pivot2); | 301 int comp_pivot2 = compare(ak, pivot2); |
| 300 if (comp_pivot2 == 0) { | 302 if (comp_pivot2 == 0) { |
| 301 while (true) { | 303 bool done = false; |
| 304 while (!done) { |
| 302 int comp = compare(a[great], pivot2); | 305 int comp = compare(a[great], pivot2); |
| 303 if (comp == 0) { | 306 if (comp == 0) { |
| 304 great--; | 307 great--; |
| 305 if (great < k) break; | 308 if (great < k) done = true; |
| 306 // This is the only location inside the loop where a new | 309 // This is the only location inside the loop where a new |
| 307 // iteration is started. | 310 // iteration is started. |
| 308 // continue; | 311 // continue; |
| 309 } else { | 312 } else { |
| 310 // a[great] < pivot2. | 313 // a[great] < pivot2. |
| 311 comp = compare(a[great], pivot1); | 314 comp = compare(a[great], pivot1); |
| 312 if (comp < 0) { | 315 if (comp < 0) { |
| 313 // Triple exchange. | 316 // Triple exchange. |
| 314 a[k] = a[less]; | 317 a[k] = a[less]; |
| 315 a[less++] = a[great]; | 318 a[less++] = a[great]; |
| 316 a[great--] = ak; | 319 a[great--] = ak; |
| 317 } else { | 320 } else { |
| 318 // a[great] == pivot1. | 321 // a[great] == pivot1. |
| 319 a[k] = a[great]; | 322 a[k] = a[great]; |
| 320 a[great--] = ak; | 323 a[great--] = ak; |
| 321 } | 324 } |
| 322 break; | 325 done = true; |
| 323 } | 326 } |
| 324 } | 327 } |
| 325 } | 328 } |
| 326 } | 329 } |
| 327 } | 330 } |
| 328 // The second partition has now been cleared of pivot elements and looks | 331 // The second partition has now been cleared of pivot elements and looks |
| 329 // as follows: | 332 // as follows: |
| 330 // [ * | > pivot1 && < pivot2 | * ] | 333 // [ * | > pivot1 && < pivot2 | * ] |
| 331 // ^ ^ | 334 // ^ ^ |
| 332 // less great | 335 // less great |
| 333 // Sort the second partition using recursive descent. | 336 // Sort the second partition using recursive descent. |
| 334 _doSort(a, less, great, compare); | 337 _doSort(a, less, great, compare); |
| 335 } else { | 338 } else { |
| 336 // The second partition looks as follows: | 339 // The second partition looks as follows: |
| 337 // [ * | >= pivot1 && <= pivot2 | * ] | 340 // [ * | >= pivot1 && <= pivot2 | * ] |
| 338 // ^ ^ | 341 // ^ ^ |
| 339 // less great | 342 // less great |
| 340 // Simply sort it by recursive descent. | 343 // Simply sort it by recursive descent. |
| 341 _doSort(a, less, great, compare); | 344 _doSort(a, less, great, compare); |
| 342 } | 345 } |
| 343 } | 346 } |
| 344 } | 347 } |
| OLD | NEW |