sort.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. * Copyright 2010-2023 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
  4. */
  5. #ifndef BX_SORT_H_HEADER_GUARD
  6. #define BX_SORT_H_HEADER_GUARD
  7. #include "bx.h"
  8. #include "math.h"
  9. #include "string.h"
  10. namespace bx
  11. {
  12. /// The function compares the `_lhs` and `_rhs` values.
  13. ///
  14. /// @returns Returns value:
  15. /// - less than zero if `_lhs` is less than `_rhs`
  16. /// - zero if `_lhs` is equivalent to `_rhs`
  17. /// - greater than zero if `_lhs` is greater than `_rhs`
  18. ///
  19. typedef int32_t (*ComparisonFn)(const void* _lhs, const void* _rhs);
  20. /// The function compares the `_lhs` and `_rhs` values.
  21. ///
  22. /// @returns Returns value:
  23. /// - less than zero if `_lhs` is less than `_rhs`
  24. /// - zero if `_lhs` is equivalent to `_rhs`
  25. /// - greater than zero if `_lhs` is greater than `_rhs`
  26. ///
  27. template<typename Ty>
  28. int32_t compareAscending(const void* _lhs, const void* _rhs);
  29. /// The function compares the `_lhs` and `_rhs` values.
  30. ///
  31. /// @returns Returns value:
  32. /// - less than zero if `_lhs` is greated than `_rhs`
  33. /// - zero if `_lhs` is equivalent to `_rhs`
  34. /// - greater than zero if `_lhs` is less than `_rhs`
  35. ///
  36. template<typename Ty>
  37. int32_t compareDescending(const void* _lhs, const void* _rhs);
  38. /// Performs sort (Quick Sort algorithm).
  39. ///
  40. /// @param _data Pointer to array data.
  41. /// @param _num Number of elements.
  42. /// @param _stride Element stride in bytes.
  43. /// @param _fn Comparison function.
  44. ///
  45. void quickSort(
  46. void* _data
  47. , uint32_t _num
  48. , uint32_t _stride
  49. , const ComparisonFn _fn
  50. );
  51. /// Performs sort (Quick Sort algorithm).
  52. ///
  53. /// @param _data Pointer to array data.
  54. /// @param _num Number of elements.
  55. /// @param _stride Element stride in bytes.
  56. /// @param _fn Comparison function.
  57. ///
  58. template<typename Ty>
  59. void quickSort(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
  60. /// Performs sort (Quick Sort algorithm).
  61. ///
  62. /// @param _data Pointer to array data.
  63. /// @param _num Number of elements.
  64. /// @param _fn Comparison function.
  65. ///
  66. template<typename Ty>
  67. void quickSort(Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
  68. /// Performs reordering of duplicate elements in the array in the way that unique elements
  69. /// are sorted to the front of array, and duplicates are after the return value index.
  70. ///
  71. /// @param _data Pointer to sorted array data.
  72. /// @param _num Number of elements.
  73. /// @param _stride Element stride in bytes.
  74. /// @param _fn Comparison function.
  75. ///
  76. /// @remarks Array must be sorted!
  77. ///
  78. /// @returns Returns the count of unique elements.
  79. ///
  80. uint32_t unique(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn);
  81. /// Performs reordering of duplicate elements in the array in the way that unique elements
  82. /// are sorted to the front of array, and duplicates are after the return value index.
  83. ///
  84. /// @param _data Pointer to sorted array data.
  85. /// @param _num Number of elements.
  86. /// @param _stride Element stride in bytes.
  87. /// @param _fn Comparison function.
  88. ///
  89. /// @remarks Array must be sorted!
  90. ///
  91. /// @returns Returns the count of unique elements.
  92. ///
  93. template<typename Ty>
  94. uint32_t unique(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
  95. /// Performs reordering of duplicate elements in the array in the way that unique elements
  96. /// are sorted to the front of array, and duplicates are after the return value index.
  97. ///
  98. /// @param _data Pointer to sorted array data.
  99. /// @param _num Number of elements.
  100. /// @param _fn Comparison function.
  101. ///
  102. /// @remarks Array must be sorted!
  103. ///
  104. /// @returns Returns the count of unique elements.
  105. ///
  106. template<typename Ty>
  107. uint32_t unique(Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
  108. /// Performs check if array is sorted.
  109. ///
  110. /// @param _data Pointer to sorted array data.
  111. /// @param _num Number of elements.
  112. /// @param _stride Element stride in bytes.
  113. /// @param _fn Comparison function.
  114. ///
  115. /// @returns Returns `true` if array is sorted, otherwise returns `false`.
  116. ///
  117. bool isSorted(
  118. const void* _data
  119. , uint32_t _num
  120. , uint32_t _stride
  121. , const ComparisonFn _fn
  122. );
  123. /// Performs check if array is sorted.
  124. ///
  125. /// @param _data Pointer to sorted array data.
  126. /// @param _num Number of elements.
  127. /// @param _stride Element stride in bytes.
  128. /// @param _fn Comparison function.
  129. ///
  130. /// @returns Returns `true` if array is sorted, otherwise returns `false`.
  131. ///
  132. template<typename Ty>
  133. bool isSorted(const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
  134. /// Performs check if array is sorted.
  135. ///
  136. /// @param _data Pointer to sorted array data.
  137. /// @param _num Number of elements.
  138. /// @param _fn Comparison function.
  139. ///
  140. /// @returns Returns `true` if array is sorted, otherwise returns `false`.
  141. ///
  142. template<typename Ty>
  143. bool isSorted(const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
  144. /// Returns an index to the first element greater or equal than the `_key` value.
  145. ///
  146. /// @param _key Pointer to the key to search for.
  147. /// @param _data Pointer to sorted array data.
  148. /// @param _num Number of elements.
  149. /// @param _stride Element stride in bytes.
  150. /// @param _fn Comparison function.
  151. ///
  152. /// @remarks Array must be sorted!
  153. ///
  154. /// @returns Returns an index to the first element greater or equal than the `_key` value.
  155. ///
  156. uint32_t lowerBound(const void* _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn);
  157. /// Returns an index to the first element greater or equal than the `_key` value.
  158. ///
  159. /// @param _key Pointer to the key to search for.
  160. /// @param _data Pointer to sorted array data.
  161. /// @param _num Number of elements.
  162. /// @param _fn Comparison function.
  163. ///
  164. /// @remarks Array must be sorted!
  165. ///
  166. /// @returns Returns an index to the first element greater or equal than the `_key` value.
  167. ///
  168. template<typename Ty>
  169. uint32_t lowerBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
  170. /// Returns an index to the first element greater or equal than the `_key` value.
  171. ///
  172. /// @param _key Pointer to the key to search for.
  173. /// @param _data Pointer to sorted array data.
  174. /// @param _num Number of elements.
  175. /// @param _stride Element stride in bytes.
  176. /// @param _fn Comparison function.
  177. ///
  178. /// @remarks Array must be sorted!
  179. ///
  180. /// @returns Returns an index to the first element greater or equal than the `_key` value.
  181. ///
  182. template<typename Ty>
  183. uint32_t lowerBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
  184. /// Returns an index to the first element greater than the `_key` value.
  185. ///
  186. /// @param _key Pointer to the key to search for.
  187. /// @param _data Pointer to sorted array data.
  188. /// @param _num Number of elements.
  189. /// @param _stride Element stride in bytes.
  190. /// @param _fn Comparison function.
  191. ///
  192. /// @remarks Array must be sorted!
  193. ///
  194. /// @returns Returns an index to the first element greater than the `_key` value.
  195. ///
  196. uint32_t upperBound(const void* _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn);
  197. /// Returns an index to the first element greater than the `_key` value.
  198. ///
  199. /// @param _key Pointer to the key to search for.
  200. /// @param _data Pointer to sorted array data.
  201. /// @param _num Number of elements.
  202. /// @param _fn Comparison function.
  203. ///
  204. /// @remarks Array must be sorted!
  205. ///
  206. /// @returns Returns an index to the first element greater than the `_key` value.
  207. ///
  208. template<typename Ty>
  209. uint32_t upperBound(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
  210. /// Returns an index to the first element greater than the `_key` value.
  211. ///
  212. /// @param _key Pointer to the key to search for.
  213. /// @param _data Pointer to sorted array data.
  214. /// @param _num Number of elements.
  215. /// @param _stride Element stride in bytes.
  216. /// @param _fn Comparison function.
  217. ///
  218. /// @remarks Array must be sorted!
  219. ///
  220. /// @returns Returns an index to the first element greater than the `_key` value.
  221. ///
  222. template<typename Ty>
  223. uint32_t upperBound(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn = compareAscending<Ty>);
  224. /// Performs binary search of a sorted array.
  225. ///
  226. /// @param _key Pointer to the key to search for.
  227. /// @param _data Pointer to sorted array data.
  228. /// @param _num Number of elements.
  229. /// @param _stride Element stride in bytes.
  230. /// @param _fn Comparison function.
  231. ///
  232. /// @remarks Array must be sorted!
  233. ///
  234. /// @returns Returns positive value index of element if found, or negative number that is bitwise
  235. /// complement (~) of the index of the next element that's larger than item.
  236. ///
  237. int32_t binarySearch(
  238. const void* _key
  239. , const void* _data
  240. , uint32_t _num
  241. , uint32_t _stride
  242. , const ComparisonFn _fn
  243. );
  244. /// Performs binary search of a sorted array.
  245. ///
  246. /// @param _key Pointer to the key to search for.
  247. /// @param _data Pointer to sorted array data.
  248. /// @param _num Number of elements.
  249. /// @param _fn Comparison function.
  250. ///
  251. /// @remarks Array must be sorted!
  252. ///
  253. /// @returns Returns positive value index of element if found, or negative number that is bitwise
  254. /// complement (~) of the index of the next element that's larger than item.
  255. ///
  256. template<typename Ty>
  257. int32_t binarySearch(const Ty& _key, const Ty* _data, uint32_t _num, const ComparisonFn _fn = compareAscending<Ty>);
  258. /// Performs binary search of a sorted array.
  259. ///
  260. /// @param _key Pointer to the key to search for.
  261. /// @param _data Pointer to sorted array data.
  262. /// @param _num Number of elements.
  263. /// @param _stride Element stride in bytes.
  264. /// @param _fn Comparison function.
  265. ///
  266. /// @remarks Array must be sorted!
  267. ///
  268. /// @returns Returns positive value index of element if found, or negative number that is bitwise
  269. /// complement (~) of the index of the next element that's larger than item.
  270. ///
  271. template<typename Ty>
  272. int32_t binarySearch(const Ty& _key, const void* _data, uint32_t _num, uint32_t _stride = sizeof(Ty), const ComparisonFn _fn = compareAscending<Ty>);
  273. ///
  274. void radixSort(
  275. uint32_t* _keys
  276. , uint32_t* _tempKeys
  277. , uint32_t _size
  278. );
  279. ///
  280. template <typename Ty>
  281. void radixSort(
  282. uint32_t* _keys
  283. , uint32_t* _tempKeys
  284. , Ty* _values
  285. , Ty* _tempValues
  286. , uint32_t _size
  287. );
  288. ///
  289. void radixSort(
  290. uint64_t* _keys
  291. , uint64_t* _tempKeys
  292. , uint32_t _size
  293. );
  294. ///
  295. template <typename Ty>
  296. void radixSort(
  297. uint64_t* _keys
  298. , uint64_t* _tempKeys
  299. , Ty* _values
  300. , Ty* _tempValues
  301. , uint32_t _size
  302. );
  303. } // namespace bx
  304. #include "inline/sort.inl"
  305. #endif // BX_SORT_H_HEADER_GUARD