algorithm 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #ifndef __GBLIBCPP_ALGORITHM__
  2. #define __GBLIBCPP_ALGORITHM__
  3. #include <functional>
  4. #include <utility>
  5. #include <initializer_list>
  6. #include <cstddef>
  7. namespace std {
  8. template <typename RandomIter, typename Compare>
  9. constexpr void make_heap(RandomIter first, RandomIter last, Compare comp)
  10. {
  11. auto len = last - first;
  12. if (len < 2)
  13. return;
  14. auto idx = len / 2 - 1;
  15. for (;;) {
  16. auto& val = first[idx];
  17. auto left = idx * 2 + 1;
  18. auto right = left + 1;
  19. if (right < len) {
  20. auto& left_val = first[left];
  21. auto& right_val = first[right];
  22. if (comp(left_val, right_val)) {
  23. if (comp(val, right_val)) {
  24. std::swap(val, right_val);
  25. idx = right;
  26. continue;
  27. }
  28. } else {
  29. if (comp(val, left_val)) {
  30. std::swap(val, left_val);
  31. idx = left;
  32. continue;
  33. }
  34. }
  35. } else if (left < len) {
  36. auto& left_val = first[left];
  37. if (comp(val, left_val)) {
  38. std::swap(val, left_val);
  39. idx = left;
  40. continue;
  41. }
  42. }
  43. if (idx == 0)
  44. break;
  45. --idx;
  46. }
  47. }
  48. template <typename RandomIter>
  49. constexpr void make_heap(RandomIter first, RandomIter last)
  50. {
  51. make_heap(first, last, std::less<typename std::decay_t<decltype(*first)>>());
  52. }
  53. template <typename RandomIter, typename Compare>
  54. constexpr void push_heap(RandomIter first, RandomIter last, Compare comp)
  55. {
  56. auto len = last - first;
  57. if (len < 2)
  58. return;
  59. auto idx = len - 1;
  60. for (;;) {
  61. auto parent = (idx - 1) / 2;
  62. if (parent == idx)
  63. break;
  64. auto& val = first[idx];
  65. auto& parent_val = first[parent];
  66. if (comp(parent_val, val)) {
  67. std::swap(val, parent_val);
  68. idx = parent;
  69. continue;
  70. }
  71. break;
  72. }
  73. }
  74. template <typename RandomIter>
  75. constexpr void push_heap(RandomIter first, RandomIter last)
  76. {
  77. push_heap(first, last, std::less<typename std::decay_t<decltype(*first)>>());
  78. }
  79. template <typename RandomIter, typename Compare>
  80. constexpr void pop_heap(RandomIter first, RandomIter last, Compare comp)
  81. {
  82. auto len = last - first;
  83. if (len < 2)
  84. return;
  85. std::swap(first[0], first[len - 1]);
  86. auto idx = 0;
  87. for (;;) {
  88. auto& val = first[idx];
  89. auto left = idx * 2 + 1;
  90. auto right = left + 1;
  91. if (right < len - 1) {
  92. auto& left_val = first[left];
  93. auto& right_val = first[right];
  94. if (comp(left_val, right_val)) {
  95. if (comp(val, right_val)) {
  96. std::swap(val, right_val);
  97. idx = right;
  98. continue;
  99. }
  100. } else {
  101. if (comp(val, left_val)) {
  102. std::swap(val, left_val);
  103. idx = left;
  104. continue;
  105. }
  106. }
  107. } else if (left < len - 1) {
  108. auto& left_val = first[left];
  109. if (comp(val, left_val)) {
  110. std::swap(val, left_val);
  111. idx = left;
  112. continue;
  113. }
  114. }
  115. if (idx == 0)
  116. break;
  117. --idx;
  118. }
  119. }
  120. template <typename RandomIter>
  121. constexpr void pop_heap(RandomIter first, RandomIter last)
  122. {
  123. pop_heap(first, last, std::less<typename std::decay_t<decltype(*first)>>());
  124. }
  125. template <typename RandomIter, typename Compare>
  126. constexpr void sort(RandomIter first, RandomIter last, Compare comp)
  127. {
  128. auto len = last - first;
  129. std::make_heap(first, last, comp);
  130. for (auto i = len - 1; i > 0; --i) {
  131. std::swap(first[0], first[i]);
  132. auto idx = 0;
  133. for (;;) {
  134. auto& val = first[idx];
  135. auto left = idx * 2 + 1;
  136. auto right = left + 1;
  137. if (right < i) {
  138. auto& left_val = first[left];
  139. auto& right_val = first[right];
  140. if (comp(left_val, right_val)) {
  141. if (comp(val, right_val)) {
  142. std::swap(val, right_val);
  143. idx = right;
  144. continue;
  145. }
  146. } else {
  147. if (comp(val, left_val)) {
  148. std::swap(val, left_val);
  149. idx = left;
  150. continue;
  151. }
  152. }
  153. } else if (left < i) {
  154. auto& left_val = first[left];
  155. if (comp(val, left_val)) {
  156. std::swap(val, left_val);
  157. idx = left;
  158. continue;
  159. }
  160. }
  161. if (idx == 0)
  162. break;
  163. --idx;
  164. }
  165. }
  166. }
  167. template <typename RandomIter>
  168. constexpr void sort(RandomIter first, RandomIter last)
  169. {
  170. sort(first, last, std::less<typename std::decay_t<decltype(*first)>>());
  171. }
  172. template <typename T>
  173. constexpr const T& min(const T& a, const T& b)
  174. {
  175. return a < b ? a : b;
  176. }
  177. template <typename T>
  178. constexpr const T& max(const T& a, const T& b)
  179. {
  180. return a > b ? a : b;
  181. }
  182. } // namespace std
  183. #endif