sort.odin 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package sort
  2. import "core:mem"
  3. bubble_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
  4. assert(f != nil);
  5. count := len(array);
  6. init_j, last_j := 0, count-1;
  7. for {
  8. init_swap, prev_swap := -1, -1;
  9. for j in init_j..last_j-1 {
  10. if f(array[j], array[j+1]) > 0 {
  11. array[j], array[j+1] = array[j+1], array[j];
  12. prev_swap = j;
  13. if init_swap == -1 do init_swap = j;
  14. }
  15. }
  16. if prev_swap == -1 do return;
  17. init_j = max(init_swap-1, 0);
  18. last_j = prev_swap;
  19. }
  20. }
  21. bubble_sort :: proc(array: $A/[]$T) {
  22. count := len(array);
  23. init_j, last_j := 0, count-1;
  24. for {
  25. init_swap, prev_swap := -1, -1;
  26. for j in init_j..last_j-1 {
  27. if array[j] > array[j+1] {
  28. array[j], array[j+1] = array[j+1], array[j];
  29. prev_swap = j;
  30. if init_swap == -1 do init_swap = j;
  31. }
  32. }
  33. if prev_swap == -1 do return;
  34. init_j = max(init_swap-1, 0);
  35. last_j = prev_swap;
  36. }
  37. }
  38. quick_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
  39. assert(f != nil);
  40. a := array;
  41. n := len(a);
  42. if n < 2 do return;
  43. p := a[n/2];
  44. i, j := 0, n-1;
  45. loop: for {
  46. for f(a[i], p) < 0 do i += 1;
  47. for f(p, a[j]) < 0 do j -= 1;
  48. if i >= j do break loop;
  49. a[i], a[j] = a[j], a[i];
  50. i += 1;
  51. j -= 1;
  52. }
  53. quick_sort_proc(a[0:i], f);
  54. quick_sort_proc(a[i:n], f);
  55. }
  56. quick_sort :: proc(array: $A/[]$T) {
  57. a := array;
  58. n := len(a);
  59. if n < 2 do return;
  60. p := a[n/2];
  61. i, j := 0, n-1;
  62. loop: for {
  63. for a[i] < p do i += 1;
  64. for p < a[j] do j -= 1;
  65. if i >= j do break loop;
  66. a[i], a[j] = a[j], a[i];
  67. i += 1;
  68. j -= 1;
  69. }
  70. quick_sort(a[0:i]);
  71. quick_sort(a[i:n]);
  72. }
  73. _log2 :: proc(n: int) -> int {
  74. res := 0;
  75. for ; n != 0; n >>= 1 do res += 1;
  76. return res;
  77. }
  78. merge_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
  79. merge_slices :: proc(arr1, arr2, out: A, f: proc(T, T) -> int) {
  80. N1, N2 := len(arr1), len(arr2);
  81. i, j := 0, 0;
  82. for k in 0..N1+N2-1 {
  83. if j == N2 || i < N1 && j < N2 && f(arr1[i], arr2[j]) < 0 {
  84. out[k] = arr1[i];
  85. i += 1;
  86. } else {
  87. out[k] = arr2[j];
  88. j += 1;
  89. }
  90. }
  91. }
  92. assert(f != nil);
  93. arr1 := array;
  94. N := len(arr1);
  95. arr2 := make([]T, N);
  96. defer free(arr2);
  97. a, b, m, M := N/2, N, 1, _log2(N);
  98. for i in 0..M {
  99. for j in 0..a-1 {
  100. k := 2*j*m;
  101. merge_slices(arr1[k:k+m], arr1[k+m:k+m+m], arr2[k:], f);
  102. }
  103. if N-b > m {
  104. k := 2*a*m;
  105. merge_slices(arr1[k:k+m], arr1[k+m : k+m+(N-b)&(m-1)], arr2[k:], f);
  106. } else {
  107. copy(arr2[b:N], arr1[b:N]);
  108. }
  109. arr1, arr2 = arr2, arr1;
  110. m <<= 1;
  111. a >>= 1;
  112. b = a << uint(i) << 2;
  113. }
  114. if M & 1 == 0 do copy(arr2, arr1);
  115. }
  116. merge_sort :: proc(array: $A/[]$T) {
  117. merge_slices :: proc(arr1, arr2, out: A) {
  118. N1, N2 := len(arr1), len(arr2);
  119. i, j := 0, 0;
  120. for k in 0..N1+N2-1 {
  121. if j == N2 || i < N1 && j < N2 && arr1[i] < arr2[j] {
  122. out[k] = arr1[i];
  123. i += 1;
  124. } else {
  125. out[k] = arr2[j];
  126. j += 1;
  127. }
  128. }
  129. }
  130. arr1 := array;
  131. N := len(arr1);
  132. arr2 := make([]T, N);
  133. defer free(arr2);
  134. a, b, m, M := N/2, N, 1, _log2(N);
  135. for i in 0..M {
  136. for j in 0..a-1 {
  137. k := 2*j*m;
  138. merge_slices(arr1[k:k+m], arr1[k+m:k+m+m], arr2[k:]);
  139. }
  140. if N-b > m {
  141. k := 2*a*m;
  142. merge_slices(arr1[k:k+m], arr1[k+m : k+m+(N-b)&(m-1)], arr2[k:]);
  143. } else {
  144. copy(arr2[b:N], arr1[b:N]);
  145. }
  146. arr1, arr2 = arr2, arr1;
  147. m <<= 1;
  148. a >>= 1;
  149. b = a << uint(i) << 2;
  150. }
  151. if M & 1 == 0 do copy(arr2, arr1);
  152. }
  153. compare_ints :: proc(a, b: int) -> int {
  154. switch delta := a - b; {
  155. case delta < 0: return -1;
  156. case delta > 0: return +1;
  157. }
  158. return 0;
  159. }
  160. compare_f32s :: proc(a, b: f32) -> int {
  161. switch delta := a - b; {
  162. case delta < 0: return -1;
  163. case delta > 0: return +1;
  164. }
  165. return 0;
  166. }
  167. compare_f64s :: proc(a, b: f64) -> int {
  168. switch delta := a - b; {
  169. case delta < 0: return -1;
  170. case delta > 0: return +1;
  171. }
  172. return 0;
  173. }
  174. compare_strings :: proc(a, b: string) -> int {
  175. return mem.compare_byte_ptrs(&a[0], &b[0], min(len(a), len(b)));
  176. }