quicksort.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /****************************************************************************
  2. *
  3. * MODULE: iostream
  4. *
  5. * COPYRIGHT (C) 2007 Laura Toma
  6. *
  7. *
  8. * Iostream is a library that implements streams, external memory
  9. * sorting on streams, and an external memory priority queue on
  10. * streams. These are the fundamental components used in external
  11. * memory algorithms.
  12. * Credits: The library was developed by Laura Toma. The kernel of
  13. * class STREAM is based on the similar class existent in the GPL TPIE
  14. * project developed at Duke University. The sorting and priority
  15. * queue have been developed by Laura Toma based on communications
  16. * with Rajiv Wickremesinghe. The library was developed as part of
  17. * porting Terraflow to GRASS in 2001. PEARL upgrades in 2003 by
  18. * Rajiv Wickremesinghe as part of the Terracost project.
  19. *
  20. * This program is free software; you can redistribute it and/or modify
  21. * it under the terms of the GNU General Public License as published by
  22. * the Free Software Foundation; either version 2 of the License, or
  23. * (at your option) any later version.
  24. *
  25. * This program is distributed in the hope that it will be useful,
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  28. * General Public License for more details. *
  29. * **************************************************************************/
  30. #ifndef _QUICKSORT_H
  31. #define _QUICKSORT_H
  32. #include <stdlib.h> //for random()
  33. // The class represented by CMPR, must have a member function called
  34. // "compare" which is used for sorting
  35. /* ---------------------------------------------------------------------- */
  36. // On return from partition(), everything at or below pivot will be
  37. // less that or equal to everything above it. Furthermore, it will
  38. // not be 0 since this will leave us to recurse on the whole array
  39. // again.
  40. template<class T, class CMPR>
  41. void partition(T *data, size_t n, size_t &pivot, CMPR &cmp) {
  42. T *ptpart, tpart;
  43. T *p, *q;
  44. T t0;
  45. // Try to get a good partition value and avoid being bitten by already
  46. // sorted input.
  47. //ptpart = data + (random() % n);
  48. #ifdef __MINGW32__
  49. ptpart = data + (rand() % n);
  50. #else
  51. ptpart = data + (random() % n);
  52. #endif
  53. tpart = *ptpart;
  54. *ptpart = data[0];
  55. data[0] = tpart;
  56. // Walk through the array and partition it.
  57. for (p = data - 1, q = data + n; ; ) {
  58. do {
  59. q--;
  60. } while (cmp.compare(*q, tpart) > 0);
  61. do {
  62. p++;
  63. } while (cmp.compare(*p, tpart) < 0);
  64. if (p < q) {
  65. t0 = *p;
  66. *p = *q;
  67. *q = t0;
  68. } else {
  69. pivot = q - data;
  70. break;
  71. }
  72. }
  73. }
  74. /* ---------------------------------------------------------------------- */
  75. template<class T, class CMPR>
  76. void insertionsort(T *data, size_t n, CMPR &cmp) {
  77. T *p, *q, test;
  78. for (p = data + 1; p < data + n; p++) {
  79. for (q = p - 1, test = *p; (cmp.compare(*q, test) > 0); q--) {
  80. *(q+1) = *q;
  81. if (q==data) {
  82. q--; // to make assignment below correct
  83. break;
  84. }
  85. }
  86. *(q+1) = test;
  87. }
  88. }
  89. /* ---------------------------------------------------------------------- */
  90. template<class T, class CMPR>
  91. void quicksort(T *data, size_t n, CMPR &cmp, size_t min_len = 20) {
  92. size_t pivot;
  93. if (n < min_len) {
  94. insertionsort(data, n, cmp);
  95. return;
  96. }
  97. //else
  98. partition(data, n, pivot, cmp);
  99. quicksort(data, pivot + 1, cmp, min_len);
  100. quicksort(data + pivot + 1, n - pivot - 1, cmp, min_len);
  101. }
  102. #endif // _QUICKSORT_H