heaputil.c 1.5 KB

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