heaputil.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "precompile.h"
  2. #include "heaputil.h"
  3. #include "dbgutil.h"
  4. #include <winpr/wtypes.h>
  5. /* heap */
  6. static void swap_elem(void**arr, int x, int y)
  7. {
  8. void* t = arr[x];
  9. arr[x] = arr[y];
  10. arr[y] = t;
  11. }
  12. TOOLKIT_API void heap_up(void**arr, int arr_n, int slot, heap_priority_cmp prio_cmp)
  13. {
  14. int i;
  15. TOOLKIT_ASSERT(arr);
  16. TOOLKIT_ASSERT(prio_cmp);
  17. i = slot;
  18. while (i) {
  19. int p = heap_parent(i);
  20. if (prio_cmp(arr[i], arr[p]) < 0) {
  21. swap_elem(arr, i, p);
  22. i = p;
  23. } else {
  24. break;
  25. }
  26. }
  27. }
  28. TOOLKIT_API void heap_down(void**arr, int arr_n, int slot, heap_priority_cmp prio_cmp)
  29. {
  30. int i = slot;
  31. int n = arr_n;
  32. TOOLKIT_ASSERT(arr);
  33. TOOLKIT_ASSERT(prio_cmp);
  34. while (i < n) {
  35. int l = heap_left_child(i);
  36. int r = heap_right_child(i);
  37. if (r < n) {
  38. int min = (prio_cmp(arr[l], arr[r]) < 0) ? l : r;
  39. if (prio_cmp(arr[min], arr[i]) < 0) {
  40. swap_elem(arr, i, min);
  41. i = min;
  42. } else {
  43. break;
  44. }
  45. } else if (l < n) { /* r is out of range */
  46. if (prio_cmp(arr[l], arr[i]) < 0) {
  47. swap_elem(arr, i, l);
  48. i = l;
  49. }
  50. else{
  51. break;
  52. }
  53. } else {
  54. break;
  55. }
  56. }
  57. }
  58. TOOLKIT_API void heap_push(void**arr, int *arr_n, void* obj, heap_priority_cmp prio_cmp)
  59. {
  60. TOOLKIT_ASSERT(arr);
  61. TOOLKIT_ASSERT(arr_n);
  62. TOOLKIT_ASSERT(obj);
  63. TOOLKIT_ASSERT(prio_cmp);
  64. arr[*arr_n] = obj;
  65. ++*arr_n;
  66. heap_up(arr, *arr_n, *arr_n-1, prio_cmp);
  67. }
  68. TOOLKIT_API void* heap_pop(void** arr, int *arr_n, heap_priority_cmp prio_cmp)
  69. {
  70. void *root = NULL;
  71. TOOLKIT_ASSERT(arr);
  72. TOOLKIT_ASSERT(arr_n);
  73. TOOLKIT_ASSERT(prio_cmp);
  74. if (*arr_n) {
  75. root = arr[0];
  76. --*arr_n;
  77. }
  78. if (*arr_n) {
  79. arr[0] = arr[*arr_n];
  80. heap_down(arr, *arr_n, 0, prio_cmp);
  81. }
  82. return root;
  83. }