qsort.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * This file lifted in toto from 'Dlibs' on the atari ST (RdeBath)
  3. *
  4. *
  5. * Dale Schumacher 399 Beacon Ave.
  6. * (alias: Dalnefre') St. Paul, MN 55104
  7. * dal@syntel.UUCP United States of America
  8. * "It's not reality that's important, but how you perceive things."
  9. */
  10. #include <string.h>
  11. char *_qbuf = 0; /* pointer to storage for qsort() */
  12. #define PIVOT ((i+j)>>1)
  13. #define moveitem(dst,src,size) if(dst != src) memcpy(dst, src, size)
  14. static void _wqsort(base, lo, hi, cmp)
  15. register int *base;
  16. register int lo;
  17. register int hi;
  18. register int (*cmp) ();
  19. {
  20. int k;
  21. register int i, j, t;
  22. register int *p = &k;
  23. while (hi > lo) {
  24. i = lo;
  25. j = hi;
  26. t = PIVOT;
  27. *p = base[t];
  28. base[t] = base[i];
  29. base[i] = *p;
  30. while (i < j) {
  31. while (((*cmp) ((base + j), p)) > 0)
  32. --j;
  33. base[i] = base[j];
  34. while ((i < j) && (((*cmp) ((base + i), p)) <= 0))
  35. ++i;
  36. base[j] = base[i];
  37. }
  38. base[i] = *p;
  39. if ((i - lo) < (hi - i)) {
  40. _wqsort(base, lo, (i - 1), cmp);
  41. lo = i + 1;
  42. } else {
  43. _wqsort(base, (i + 1), hi, cmp);
  44. hi = i - 1;
  45. }
  46. }
  47. }
  48. static void _lqsort(base, lo, hi, cmp)
  49. register long *base;
  50. register int lo;
  51. register int hi;
  52. register int (*cmp) ();
  53. {
  54. long k;
  55. register int i, j, t;
  56. register long *p = &k;
  57. while (hi > lo) {
  58. i = lo;
  59. j = hi;
  60. t = PIVOT;
  61. *p = base[t];
  62. base[t] = base[i];
  63. base[i] = *p;
  64. while (i < j) {
  65. while (((*cmp) ((base + j), p)) > 0)
  66. --j;
  67. base[i] = base[j];
  68. while ((i < j) && (((*cmp) ((base + i), p)) <= 0))
  69. ++i;
  70. base[j] = base[i];
  71. }
  72. base[i] = *p;
  73. if ((i - lo) < (hi - i)) {
  74. _lqsort(base, lo, (i - 1), cmp);
  75. lo = i + 1;
  76. } else {
  77. _lqsort(base, (i + 1), hi, cmp);
  78. hi = i - 1;
  79. }
  80. }
  81. }
  82. static void _nqsort(base, lo, hi, size, cmp)
  83. register char *base;
  84. register int lo;
  85. register int hi;
  86. register int size;
  87. register int (*cmp) ();
  88. {
  89. register int i, j;
  90. register char *p = _qbuf;
  91. while (hi > lo) {
  92. i = lo;
  93. j = hi;
  94. p = (base + size * PIVOT);
  95. moveitem(_qbuf, p, size);
  96. moveitem(p, (base + size * i), size);
  97. moveitem((base + size * i), _qbuf, size);
  98. p = _qbuf;
  99. while (i < j) {
  100. while (((*cmp) ((base + size * j), p)) > 0)
  101. --j;
  102. moveitem((base + size * i), (base + size * j), size);
  103. while ((i < j) && (((*cmp) ((base + size * i), p)) <= 0))
  104. ++i;
  105. moveitem((base + size * j), (base + size * i), size);
  106. }
  107. moveitem((base + size * i), p, size);
  108. if ((i - lo) < (hi - i)) {
  109. _nqsort(base, lo, (i - 1), size, cmp);
  110. lo = i + 1;
  111. } else {
  112. _nqsort(base, (i + 1), hi, size, cmp);
  113. hi = i - 1;
  114. }
  115. }
  116. }
  117. extern int qsort(base, num, size, cmp)
  118. char *base;
  119. int num;
  120. int size;
  121. int (*cmp) ();
  122. {
  123. char _qtemp[128];
  124. if (_qbuf == 0) {
  125. if (size > sizeof(_qtemp)) /* records too large! */
  126. return 1;
  127. _qbuf = _qtemp;
  128. }
  129. if (size == 2)
  130. _wqsort(base, 0, num - 1, cmp);
  131. else if (size == 4)
  132. _lqsort(base, 0, num - 1, cmp);
  133. else
  134. _nqsort(base, 0, num - 1, size, cmp);
  135. if (_qbuf == _qtemp)
  136. _qbuf = 0;
  137. return 0;
  138. }