优先队列(堆)

- 日理万妓 2022-08-30 04:05 345阅读 0赞

优先队列(堆)

优先队列(堆)用于调度、排序方面,基本模型如下:

在这里插入图片描述
队列中的节点都是有优先级的,如图删除的时候是最小值节点。
heap.h

  1. struct heap_struct;
  2. typedef struct heap_struct *priority_queue;
  3. typedef int ElementType;
  4. priority_queue init(int max_elements);
  5. void destory(priority_queue h);
  6. void make_empty(priority_queue h);
  7. void insert(ElementType x, priority_queue h);
  8. ElementType delete_min(priority_queue h);
  9. ElementType find_min(priority_queue h);
  10. int is_empty(priority_queue h);
  11. int is_full(priority_queue h);
  12. ElementType find_k_min(priority_queue h,int k);
  13. struct heap_struct{
  14. int capacity;
  15. int size;
  16. ElementType * elements;
  17. };

实现中需要注意三点:
1.插入时,将待插入节点放入最后一个空穴,逐层上滤(percolate up);
2.删除时,删除根节点后,将空穴中两个儿子中较小者移入空穴;
3.当有偶数个元素时,会遇到节点只有一个儿子,小心发生错误。
应用:1.求出第K小的元素;2.求出第K大的元素。
heap.c

  1. void keep_top_k(ElementType x,priority_queue h);
  2. int main(){
  3. priority_queue h = init(10);
  4. ElementType * data = h->elements;
  5. int i = 0;
  6. for(i=1;i<100;i++){
  7. insert(i,h);
  8. }
  9. int len = h->size;
  10. for(i=0;i<len;i++)
  11. printf("%d\n",data[i]);
  12. destory(h);
  13. }
  14. priority_queue init(int max_elements){
  15. struct heap_struct * h = malloc(sizeof(struct heap_struct));
  16. h->capacity = max_elements;
  17. h->size = 0;
  18. ElementType * e = malloc(sizeof(ElementType)*(max_elements+1)); //occupy slot 0
  19. e[0] = -1;
  20. h->elements = e;
  21. return h;
  22. }
  23. void destory(priority_queue h){
  24. ElementType * e = h->elements;
  25. free(e);
  26. free(h);
  27. }
  28. void make_empty(priority_queue h){
  29. h->size = 0;
  30. }
  31. void insert(ElementType x,priority_queue h){
  32. if(h->size == h->capacity){
  33. keep_top_k(x,h);
  34. return;
  35. }
  36. int t_slot = (h->size)+1;
  37. int dest = t_slot;
  38. if(t_slot > h->capacity){
  39. printf("there is no free slot\n");
  40. return;
  41. }
  42. ElementType * data = h->elements;
  43. data[dest] = x;
  44. while(data[dest] < data[dest/2]){
  45. if(dest == 1){
  46. data[dest] = x;
  47. break;
  48. }
  49. data[dest] = data[dest/2];
  50. data[dest/2] = x;
  51. dest = dest/2;
  52. }
  53. data[dest] = x;
  54. (h->size)++;
  55. }
  56. ElementType delete_min(priority_queue h){
  57. ElementType ret;
  58. int len = h->size;
  59. int capa = h->capacity;
  60. ElementType * data = h->elements;
  61. ret = data[1];
  62. int del_posi = 1;
  63. while(del_posi <= len){
  64. if(del_posi*2 >= len){
  65. data[del_posi] = data[len];
  66. break;
  67. }
  68. else{
  69. if(data[del_posi*2]<data[del_posi*2+1]){
  70. data[del_posi] = data[del_posi*2];
  71. del_posi = del_posi*2;
  72. }
  73. else{
  74. data[del_posi] = data[del_posi*2+1];
  75. del_posi = del_posi*2+1;
  76. }
  77. }
  78. }
  79. len--;
  80. h->size = len;
  81. return ret;
  82. }
  83. ElementType find_k_min(priority_queue h,int k){
  84. ElementType ret;
  85. int i= 0 ;
  86. for(i=0;i<k;i++){
  87. ret = delete_min(h);
  88. }
  89. return ret;
  90. }
  91. void keep_top_k(ElementType x,priority_queue h){
  92. int len = h->size;
  93. int layer = 0;
  94. int i = 0;
  95. ElementType * data = h->elements;
  96. while(len!=0){
  97. len=len/2;
  98. layer++;
  99. }
  100. layer--;
  101. int po = 1;
  102. while(layer!=0){
  103. po=po*2;
  104. layer--;
  105. }
  106. int insert_po = po;
  107. int temp_max = data[po];
  108. for(i=0;i<=len;i++){
  109. if(data[i]>temp_max){
  110. temp_max = data[i];
  111. insert_po=i;
  112. }
  113. }
  114. if(x<temp_max){
  115. data[insert_po] = x;
  116. }
  117. else
  118. return;
  119. }
  120. int is_empty(priority_queue h){
  121. if(h->size == 0)
  122. return 1;
  123. else
  124. return 0;
  125. }
  126. int is_full(priority_queue h){
  127. if((h->size)==(h->capacity))
  128. return 1;
  129. else
  130. return 0;
  131. }

发表评论

表情:
评论列表 (有 0 条评论,345人围观)

还没有评论,来说两句吧...

相关阅读

    相关 优先队列

    设计一个程序模仿操作系统的进程管理问题,进 程服务按优先级高的先服务,同优先级的先到先服务的管理 原则。设文件task.txt中存放了仿真进程服务请求,其中第 一列是进程任务号