Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.6 KiB

  1. // template qsort adapted from msdev\crt\src\qsort.c
  2. // created 7/96 bobp
  3. // template<class T>
  4. // void QSort (T *base, unsigned nEl, BOOL fSortUp)
  5. //
  6. // quicksort array of T
  7. //
  8. // Uses class T member functions:
  9. // operator =
  10. // operator <=
  11. #ifndef __TQSORT_INCL
  12. #define __TQSORT_INCL
  13. template<class T>
  14. inline void Swap(T &a, T &b)
  15. {
  16. T x = a; a = b; b = x;
  17. }
  18. template<class T>
  19. static void __cdecl ShortSort (T *lo, T *hi, BOOL fUp)
  20. {
  21. T *p, *max;
  22. while (hi > lo) {
  23. max = lo;
  24. if (fUp) {
  25. for (p = lo+1; p <= hi; p++) {
  26. if ( !(*p <= *max) )
  27. max = p;
  28. }
  29. } else {
  30. for (p = lo+1; p <= hi; p++) {
  31. if ( !(*max <= *p) )
  32. max = p;
  33. }
  34. }
  35. Swap (*max, *hi);
  36. hi --;
  37. }
  38. }
  39. #define CUTOFF 8 /* testing shows that this is good value */
  40. template<class T>
  41. void QSort (T *base, unsigned nEl, BOOL fUp)
  42. {
  43. T *lo, *hi; /* ends of sub-array currently sorting */
  44. T *mid; /* points to middle of subarray */
  45. T *loguy, *higuy; /* traveling pointers for partition step */
  46. unsigned size; /* size of the sub-array */
  47. T *lostk[30], *histk[30];
  48. int stkptr; /* stack for saving sub-array to be processed */
  49. /* Note: the number of stack entries required is no more than
  50. 1 + log2(size), so 30 is sufficient for any array */
  51. if (nEl < 2)
  52. return; /* nothing to do */
  53. stkptr = 0; /* initialize stack */
  54. lo = base;
  55. hi = base + (nEl-1); /* initialize limits */
  56. recurse:
  57. size = (int)(hi - lo) + 1; /* number of el's to sort */
  58. if (size <= CUTOFF) {
  59. ShortSort(lo, hi, fUp);
  60. }
  61. else {
  62. mid = lo + (size / 2); /* find middle element */
  63. Swap(*mid, *lo); /* swap it to beginning of array */
  64. loguy = lo;
  65. higuy = hi + 1;
  66. for (;;) {
  67. if (fUp) {
  68. do {
  69. loguy ++;
  70. } while (loguy <= hi && *loguy <= *lo);
  71. do {
  72. higuy --;
  73. } while (higuy > lo && *lo <= *higuy);
  74. } else {
  75. do {
  76. loguy ++;
  77. } while (loguy <= hi && *lo <= *loguy);
  78. do {
  79. higuy --;
  80. } while (higuy > lo && *higuy <= *lo);
  81. }
  82. if (higuy < loguy)
  83. break;
  84. Swap(*loguy, *higuy);
  85. }
  86. Swap(*lo, *higuy); /* put partition element in place */
  87. if ( higuy - 1 - lo >= hi - loguy ) {
  88. if (lo + 1 < higuy) {
  89. lostk[stkptr] = lo;
  90. histk[stkptr] = higuy - 1;
  91. ++stkptr;
  92. } /* save big recursion for later */
  93. if (loguy < hi) {
  94. lo = loguy;
  95. goto recurse; /* do small recursion */
  96. }
  97. }
  98. else {
  99. if (loguy < hi) {
  100. lostk[stkptr] = loguy;
  101. histk[stkptr] = hi;
  102. ++stkptr; /* save big recursion for later */
  103. }
  104. if (lo + 1 < higuy) {
  105. hi = higuy - 1;
  106. goto recurse; /* do small recursion */
  107. }
  108. }
  109. }
  110. --stkptr;
  111. if (stkptr >= 0) {
  112. lo = lostk[stkptr];
  113. hi = histk[stkptr];
  114. goto recurse; /* pop subarray from stack */
  115. }
  116. }
  117. #endif