00001
00002
00003
00004
00005
00006
00007
00008
00009
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #define _QSORT_SWAP(a, b, t) ((void)((t = *a), (*a = *b), (*b = t)))
00103
00104
00105
00106 #define _QSORT_MAX_THRESH 4
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 #define _QSORT_STACK_SIZE (8 * sizeof(unsigned))
00121 #define _QSORT_PUSH(top, low, high) \
00122 (((top->_lo = (low)), (top->_hi = (high)), ++top))
00123 #define _QSORT_POP(low, high, top) \
00124 ((--top, (low = top->_lo), (high = top->_hi)))
00125 #define _QSORT_PUSH2(top, low, high) \
00126 (((top->_lo2 = (low)), (top->_hi2 = (high)), ++top))
00127 #define _QSORT_POP2(low, high, top) \
00128 ((--top, (low = top->_lo2), (high = top->_hi2)))
00129 #define _QSORT_STACK_NOT_EMPTY (_stack < _top)
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 #define QSORT(QSORT_TYPE,QSORT_BASE,QSORT_NELT,QSORT_LT) \
00157 { \
00158 QSORT_TYPE *const _base = (QSORT_BASE); \
00159 const unsigned _elems = (QSORT_NELT); \
00160 QSORT_TYPE _hold; \
00161 \
00162
00163
00164
00165 \
00166 \
00167 if (_elems > _QSORT_MAX_THRESH) { \
00168 QSORT_TYPE *_lo = _base; \
00169 QSORT_TYPE *_hi = _lo + _elems - 1; \
00170 struct { \
00171 QSORT_TYPE *_hi; QSORT_TYPE *_lo; \
00172 } _stack[_QSORT_STACK_SIZE], *_top = _stack + 1; \
00173 \
00174 while (_QSORT_STACK_NOT_EMPTY) { \
00175 QSORT_TYPE *_left_ptr; QSORT_TYPE *_right_ptr; \
00176 \
00177
00178
00179
00180
00181 \
00182 \
00183 QSORT_TYPE *_mid = _lo + ((_hi - _lo) >> 1); \
00184 \
00185 if (QSORT_LT (_mid, _lo)) \
00186 _QSORT_SWAP (_mid, _lo, _hold); \
00187 if (QSORT_LT (_hi, _mid)) { \
00188 _QSORT_SWAP (_mid, _hi, _hold); \
00189 if (QSORT_LT (_mid, _lo)) \
00190 _QSORT_SWAP (_mid, _lo, _hold); \
00191 } \
00192 \
00193 _left_ptr = _lo + 1; \
00194 _right_ptr = _hi - 1; \
00195 \
00196
00197
00198 \
00199 do { \
00200 while (QSORT_LT (_left_ptr, _mid)) \
00201 ++_left_ptr; \
00202 \
00203 while (QSORT_LT (_mid, _right_ptr)) \
00204 --_right_ptr; \
00205 \
00206 if (_left_ptr < _right_ptr) { \
00207 _QSORT_SWAP (_left_ptr, _right_ptr, _hold); \
00208 if (_mid == _left_ptr) \
00209 _mid = _right_ptr; \
00210 else if (_mid == _right_ptr) \
00211 _mid = _left_ptr; \
00212 ++_left_ptr; \
00213 --_right_ptr; \
00214 } \
00215 else if (_left_ptr == _right_ptr) { \
00216 ++_left_ptr; \
00217 --_right_ptr; \
00218 break; \
00219 } \
00220 } while (_left_ptr <= _right_ptr); \
00221 \
00222
00223
00224
00225 \
00226 \
00227 if (_right_ptr - _lo <= _QSORT_MAX_THRESH) { \
00228 if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \
00229 \
00230 _QSORT_POP (_lo, _hi, _top); \
00231 else \
00232 \
00233 _lo = _left_ptr; \
00234 } \
00235 else if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \
00236 \
00237 _hi = _right_ptr; \
00238 else if (_right_ptr - _lo > _hi - _left_ptr) { \
00239 \
00240 _QSORT_PUSH (_top, _lo, _right_ptr); \
00241 _lo = _left_ptr; \
00242 } \
00243 else { \
00244 \
00245 _QSORT_PUSH (_top, _left_ptr, _hi); \
00246 _hi = _right_ptr; \
00247 } \
00248 } \
00249 } \
00250 \
00251
00252
00253
00254
00255 \
00256 \
00257 { \
00258 QSORT_TYPE *const _end_ptr = _base + _elems - 1; \
00259 QSORT_TYPE *_tmp_ptr = _base; \
00260 register QSORT_TYPE *_run_ptr; \
00261 QSORT_TYPE *_thresh; \
00262 \
00263 _thresh = _base + _QSORT_MAX_THRESH; \
00264 if (_thresh > _end_ptr) \
00265 _thresh = _end_ptr; \
00266 \
00267
00268
00269 \
00270 \
00271 for (_run_ptr = _tmp_ptr + 1; _run_ptr <= _thresh; ++_run_ptr) \
00272 { \
00273 if (QSORT_LT (_run_ptr, _tmp_ptr)) \
00274 { \
00275 _tmp_ptr = _run_ptr; \
00276 } \
00277 } \
00278 \
00279 if (_tmp_ptr != _base) \
00280 _QSORT_SWAP (_tmp_ptr, _base, _hold); \
00281 \
00282
00283 \
00284 \
00285 _run_ptr = _base + 1; \
00286 ++_run_ptr; \
00287 while (_run_ptr <= _end_ptr) { \
00288 _tmp_ptr = _run_ptr - 1; \
00289 while (QSORT_LT (_run_ptr, _tmp_ptr)) \
00290 --_tmp_ptr; \
00291 \
00292 ++_tmp_ptr; \
00293 if (_tmp_ptr != _run_ptr) { \
00294 QSORT_TYPE *_trav = _run_ptr + 1; \
00295 _trav--; \
00296 while ( (_trav >= _run_ptr) ) { \
00297 QSORT_TYPE *_hi; QSORT_TYPE *_lo; \
00298 _hold = *_trav; \
00299 _hi=_lo=_trav; \
00300 _lo--; \
00301 while(_lo>=_tmp_ptr) { \
00302 *_hi = *_lo; \
00303 _hi=_lo; \
00304 _lo--; \
00305 } \
00306 *_hi = _hold; \
00307 _trav--; \
00308 } \
00309 } \
00310 ++_run_ptr; \
00311 } \
00312 } \
00313 }
00314
00315
00316 #define \
00317 QSORT2(QSORT_TYPE,QSORT_TYPE2,QSORT_BASE,QSORT_BASE2,QSORT_NELT,QSORT_LT)\
00318 { \
00319 QSORT_TYPE *const _base = (QSORT_BASE); \
00320 QSORT_TYPE2 *const _base2 = (QSORT_BASE2); \
00321 const unsigned _elems = (QSORT_NELT); \
00322 QSORT_TYPE _hold; \
00323 QSORT_TYPE2 _hold2; \
00324 \
00325
00326
00327
00328 \
00329 \
00330 if (_elems > _QSORT_MAX_THRESH) { \
00331 QSORT_TYPE *_lo = _base; \
00332 QSORT_TYPE2 *_lo2 = _base2; \
00333 QSORT_TYPE *_hi = _lo + _elems - 1; \
00334 QSORT_TYPE2 *_hi2 = _lo2 + _elems - 1; \
00335 struct { \
00336 QSORT_TYPE *_hi; QSORT_TYPE *_lo; \
00337 } _stack[_QSORT_STACK_SIZE], *_top = _stack + 1; \
00338 struct { \
00339 QSORT_TYPE2 *_hi2; QSORT_TYPE2 *_lo2; \
00340 } _stack2[_QSORT_STACK_SIZE], *_top2 = _stack2 + 1; \
00341 \
00342 while (_QSORT_STACK_NOT_EMPTY) { \
00343 QSORT_TYPE *_left_ptr; QSORT_TYPE *_right_ptr; \
00344 QSORT_TYPE2 *_left_ptr2; QSORT_TYPE2 *_right_ptr2; \
00345 \
00346
00347
00348
00349
00350 \
00351 \
00352 QSORT_TYPE *_mid = _lo + ((_hi - _lo) >> 1); \
00353 QSORT_TYPE2 *_mid2 = _lo2 + ((_hi2 - _lo2) >> 1); \
00354 \
00355 if (QSORT_LT (_mid, _lo)) \
00356 { \
00357 _QSORT_SWAP (_mid, _lo, _hold); \
00358 _QSORT_SWAP (_mid2, _lo2, _hold2); \
00359 } \
00360 if (QSORT_LT (_hi, _mid)) \
00361 { \
00362 _QSORT_SWAP (_mid, _hi, _hold); \
00363 _QSORT_SWAP (_mid2, _hi2, _hold2); \
00364 if (QSORT_LT (_mid, _lo)) \
00365 { \
00366 _QSORT_SWAP (_mid, _lo, _hold); \
00367 _QSORT_SWAP (_mid2, _lo2, _hold2); \
00368 } \
00369 } \
00370 \
00371 _left_ptr = _lo + 1; \
00372 _left_ptr2 = _lo2 + 1; \
00373 _right_ptr = _hi - 1; \
00374 _right_ptr2 = _hi2 - 1; \
00375 \
00376
00377
00378 \
00379 do { \
00380 while (QSORT_LT (_left_ptr, _mid)) \
00381 { \
00382 ++_left_ptr; \
00383 ++_left_ptr2; \
00384 } \
00385 \
00386 while (QSORT_LT (_mid, _right_ptr)) \
00387 { \
00388 --_right_ptr; \
00389 --_right_ptr2; \
00390 } \
00391 \
00392 if (_left_ptr < _right_ptr) \
00393 { \
00394 _QSORT_SWAP (_left_ptr, _right_ptr, _hold); \
00395 _QSORT_SWAP (_left_ptr2, _right_ptr2, _hold2); \
00396 if (_mid == _left_ptr) \
00397 { \
00398 _mid = _right_ptr; \
00399 _mid2 = _right_ptr2; \
00400 } \
00401 else if (_mid == _right_ptr) \
00402 { \
00403 _mid = _left_ptr; \
00404 _mid2 = _left_ptr2; \
00405 } \
00406 ++_left_ptr; \
00407 ++_left_ptr2; \
00408 --_right_ptr; \
00409 --_right_ptr2; \
00410 } \
00411 else if (_left_ptr == _right_ptr) \
00412 { \
00413 ++_left_ptr; \
00414 ++_left_ptr2; \
00415 --_right_ptr; \
00416 --_right_ptr2; \
00417 break; \
00418 } \
00419 } while (_left_ptr <= _right_ptr); \
00420 \
00421
00422
00423
00424 \
00425 \
00426 if (_right_ptr - _lo <= _QSORT_MAX_THRESH) \
00427 { \
00428 if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \
00429 { \
00430 \
00431 _QSORT_POP (_lo, _hi, _top); \
00432 _QSORT_POP2 (_lo2, _hi2, _top2); \
00433 } \
00434 else \
00435 { \
00436 \
00437 _lo = _left_ptr; \
00438 _lo2 = _left_ptr2; \
00439 } \
00440 } \
00441 else if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \
00442 { \
00443 \
00444 _hi = _right_ptr; \
00445 _hi2 = _right_ptr2; \
00446 } \
00447 else if (_right_ptr - _lo > _hi - _left_ptr) \
00448 { \
00449 \
00450 _QSORT_PUSH (_top, _lo, _right_ptr); \
00451 _QSORT_PUSH2 (_top2, _lo2, _right_ptr2); \
00452 _lo = _left_ptr; \
00453 _lo2 = _left_ptr2; \
00454 } \
00455 else \
00456 { \
00457 \
00458 _QSORT_PUSH (_top, _left_ptr, _hi); \
00459 _QSORT_PUSH2 (_top2, _left_ptr2, _hi2); \
00460 _hi = _right_ptr; \
00461 _hi2 = _right_ptr2; \
00462 } \
00463 } \
00464 } \
00465 \
00466
00467
00468
00469
00470 \
00471 \
00472 { \
00473 QSORT_TYPE *const _end_ptr = _base + _elems - 1; \
00474 QSORT_TYPE *_tmp_ptr = _base; \
00475 QSORT_TYPE2 *_tmp_ptr2 = _base2; \
00476 register QSORT_TYPE *_run_ptr; \
00477 register QSORT_TYPE2 *_run_ptr2; \
00478 QSORT_TYPE *_thresh; \
00479 \
00480 _thresh = _base + _QSORT_MAX_THRESH; \
00481 if (_thresh > _end_ptr) \
00482 { \
00483 _thresh = _end_ptr; \
00484 } \
00485 \
00486
00487
00488 \
00489 \
00490 for (_run_ptr = _tmp_ptr + 1,_run_ptr2 = _tmp_ptr2 + 1; \
00491 _run_ptr <= _thresh; ++_run_ptr,++_run_ptr2) \
00492 { \
00493 if (QSORT_LT (_run_ptr, _tmp_ptr)) \
00494 { \
00495 _tmp_ptr = _run_ptr; \
00496 _tmp_ptr2 = _run_ptr2; \
00497 } \
00498 } \
00499 \
00500 if (_tmp_ptr != _base) \
00501 { \
00502 _QSORT_SWAP (_tmp_ptr, _base, _hold); \
00503 _QSORT_SWAP (_tmp_ptr2, _base2, _hold2); \
00504 } \
00505 \
00506
00507 \
00508 \
00509 _run_ptr = _base + 1; \
00510 _run_ptr2 = _base2 + 1; \
00511 ++_run_ptr; \
00512 ++_run_ptr2; \
00513 while (_run_ptr <= _end_ptr) \
00514 { \
00515 _tmp_ptr = _run_ptr - 1; \
00516 _tmp_ptr2 = _run_ptr2 - 1; \
00517 while (QSORT_LT (_run_ptr, _tmp_ptr)) \
00518 { \
00519 --_tmp_ptr; \
00520 --_tmp_ptr2; \
00521 } \
00522 \
00523 ++_tmp_ptr; \
00524 ++_tmp_ptr2; \
00525 if (_tmp_ptr != _run_ptr) \
00526 { \
00527 QSORT_TYPE *_trav = _run_ptr + 1; \
00528 QSORT_TYPE2 *_trav2 = _run_ptr2 + 1; \
00529 _trav--; \
00530 _trav2--; \
00531 while ( (_trav >= _run_ptr) ) \
00532 { \
00533 QSORT_TYPE *_hi; QSORT_TYPE *_lo; \
00534 QSORT_TYPE2 *_hi2; QSORT_TYPE2 *_lo2; \
00535 _hold = *_trav; \
00536 _hold2 = *_trav2; \
00537 _hi=_lo=_trav; \
00538 _hi2=_lo2=_trav2; \
00539 _lo--; \
00540 _lo2--; \
00541 while(_lo>=_tmp_ptr) \
00542 { \
00543 *_hi = *_lo; \
00544 *_hi2 = *_lo2; \
00545 _hi=_lo; \
00546 _hi2=_lo2; \
00547 _lo--; \
00548 _lo2--; \
00549 } \
00550 *_hi = _hold; \
00551 *_hi2 = _hold2; \
00552 _trav--; \
00553 _trav2--; \
00554 } \
00555 } \
00556 ++_run_ptr; \
00557 ++_run_ptr2; \
00558 } \
00559 } \
00560 }