Advertisement
kaenan

Quicksort - randomized

Jan 4th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.89 KB | None | 0 0
  1. #include "stdio_wrap.h"
  2. #include "stdlib_wrap.h"
  3. #include "time.h"
  4.  
  5. int rand_n(int);
  6. int rand_range(int, int);
  7. void swap(int [], int, int);
  8.  
  9. void KR_rand_qsort(int [], int, int);
  10. void KR_qsort(int [], int, int);
  11.  
  12. void inter_sort(int [], int);
  13.  
  14. void alg_rand_qsort(int a[], int lo, int hi);
  15. void alg_qsort(int a[], int lo, int hi);
  16.  
  17. void count_itr(char *, int[], int, void (*)(int[], int, int));
  18.  
  19. // Used to count the the iterations perfomed when sorting.
  20. int itr_perf = 0;
  21.  
  22.  
  23. #define INPUT "i.txt"
  24. #define SORTED "sorted.txt"
  25. #define CHECK "result.txt"
  26.  
  27. int main()
  28. {
  29. /*
  30. int test[] = {
  31. 10, 9, 34, 14, 8, 6, 39, 1, 4, 34, 431, 43, 98, 35, 89, 349, 956, 5, 3, 43
  32. };
  33. //alg_rand_qsort(test, 0, NELEMS(test) - 1);
  34. //fprintarr(stdout, "%d ", test, NELEMS(test));
  35. */
  36.  
  37. int arr[100000];
  38. size_t n = 100000;
  39. FILE *input, *out;
  40.  
  41. file_isEmpty_(INPUT, return 0); input = ec_fopen(INPUT, "r");
  42. freadarr(input, "%d", arr, n);
  43. fclose(input);
  44.  
  45. count_itr("simple k&r", arr, n, KR_qsort);
  46. count_itr("randomized k&r", arr, n, KR_rand_qsort);
  47. out = ec_fopen(SORTED, "w"); fprintarr(out, "%d ", arr, n); fclose(out);
  48.  
  49. count_itr("simple v2", arr, n, alg_qsort);
  50. count_itr("randomized v2", arr, n, alg_rand_qsort);
  51.  
  52. out = ec_fopen(CHECK, "w"); fprintarr(out, "%d ", arr, n); fclose(out);
  53.  
  54. /* Verify. */
  55. FILE *verf, *res;
  56.  
  57. verf = ec_fopen(SORTED, "r");
  58. res = ec_fopen(CHECK, "r");
  59.  
  60. int a, b;
  61. forIn(i, 0, n) {
  62. fscanf(verf, "%d", &a);
  63. fscanf(res, "%d", &b);
  64. if (a != b) {
  65. printf("%d: %d != %d\n", i, a, b);
  66. exit(-1);
  67. }
  68. }
  69. fclose(verf); fclose(res);
  70.  
  71. puts("[OK]");
  72. return 0;
  73. }
  74.  
  75. void count_itr(char *qsort_name, int arr[], int n, void (*qsort_fn)(int arr[], int lo, int hi))
  76. {
  77. itr_perf = 0;
  78. (*qsort_fn)(arr, 0, n - 1);
  79. printf("%s: %d\n", qsort_name, itr_perf);
  80. }
  81.  
  82.  
  83. void alg_rand_qsort(int a[], int lo, int hi)
  84. {
  85. if (hi <= lo) {
  86. return;
  87. }
  88.  
  89. swap(a, lo, rand_range(lo, hi)); // ++
  90.  
  91. int key = a[lo], last = lo, rest = hi;
  92.  
  93. while (last < rest)
  94. {
  95. //if (a[i] < key) ++last; (skip)
  96. if (a[last + 1] > key) {
  97. while (a[rest] > key && last < rest) {
  98. rest--; ++itr_perf;
  99. }
  100.  
  101. if (last < rest) {
  102. swap(a, ++last, rest--);
  103. }
  104. }
  105. else { ++last; ++itr_perf; }
  106. } // Now a[lo..last] < key < a[rest+1..hi].
  107.  
  108. swap(a, lo, last); // Place pivot
  109. alg_rand_qsort(a, lo, last - 1);
  110. alg_rand_qsort(a, rest + 1, hi);
  111. }
  112.  
  113.  
  114. void alg_qsort(int a[], int lo, int hi)
  115. {
  116. if (hi <= lo) {
  117. return;
  118. }
  119.  
  120. int key = a[lo], last = lo, rest = hi;
  121.  
  122. while (last < rest)
  123. {
  124. //if (a[i] < key) ++last; (skip)
  125. if (a[last + 1] > key) {
  126. while (a[rest] > key && last < rest) {
  127. ++itr_perf;
  128. rest--;
  129. }
  130.  
  131. if (last < rest) {
  132. swap(a, ++last, rest--);
  133. }
  134. }
  135. else { ++last; ++itr_perf; }
  136. } // Now a[lo..last] < key < a[rest+1..hi].
  137.  
  138. swap(a, lo, last); // Place pivot
  139. alg_qsort(a, lo, last - 1);
  140. alg_qsort(a, rest + 1, hi);
  141. }
  142.  
  143.  
  144.  
  145. void KR_rand_qsort(int arr[], int left, int right)
  146. {
  147. int last, mid = (left + right) / 2;
  148.  
  149. if (left >= right) {
  150. return;
  151. }
  152.  
  153. swap(arr, mid, rand_range(left, right)); // ++
  154.  
  155. swap(arr, left, mid); /* move partition elem */
  156.  
  157. last = left;
  158. for (int i = left + 1; i <= right; ++i) { /* partition */
  159. if (arr[i] < arr[left]) {
  160. swap(arr, ++last, i);
  161. }
  162. ++itr_perf;
  163. }
  164.  
  165. swap(arr, left, last); /* place partition elem */
  166. KR_rand_qsort(arr, left, last - 1);
  167. KR_rand_qsort(arr, last + 1, right);
  168. }
  169.  
  170.  
  171. void KR_qsort(int v[], int left, int right)
  172. {
  173. int last, mid = (left + right) / 2;
  174.  
  175. if (left >= right)
  176. return;
  177.  
  178. swap(v, left, mid); /* move partition elem */
  179.  
  180. last = left;
  181. for (int i = left + 1; i <= right; i++) { /* partition */
  182. if (v[i] < v[left]) {
  183. swap(v, ++last, i);
  184. }
  185. ++itr_perf;
  186. }
  187.  
  188. swap(v, left, last); /* place partition elem */
  189. KR_qsort(v, left, last - 1);
  190. KR_qsort(v, last + 1, right);
  191. }
  192.  
  193.  
  194. /* Returns a number from [l, r]. */
  195. int rand_range(int l, int r)
  196. {
  197. int rand = rand_n(r - l);
  198.  
  199. return (rand < l) ? l + rand : rand;
  200. }
  201.  
  202. /* Returns a random number form [0, n]. */
  203. int rand_n(int n)
  204. {
  205. static bool init;
  206.  
  207. if (!init) {
  208. srand((unsigned int) time(NULL));
  209. }
  210.  
  211. return rand() % (n + 1);
  212. }
  213.  
  214. /* swap: interchange arr[i] and arr[j] */
  215. void swap(int arr[], int i, int j)
  216. {
  217. int temp;
  218. temp = arr[i];
  219. arr[i] = arr[j];
  220. arr[j] = temp;
  221. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement