当前位置:   article > 正文

堆的数据结构以及堆的相应操作

堆的数据结构以及堆的相应操作

堆的定义

二叉树中的堆使用顺序存储的结构来进行存储这里的堆指代的是一种数据结构

在一个关键码存在的集合中K = {K1,K2,K3,....,Kn},把它的所有元素按照完全二叉树的顺序存储方式,存储在一个一维数组中,如果根结点的元素值大于其左右孩子的值,并且每个子树都满足这种情况,其对应的堆,我们称为最大堆

堆的相关操作

  1. //Heap.h
  2. #pragma once
  3. #include<iostream>
  4. #include<stdlib.h>
  5. #include<stdbool.h>
  6. using namespace std;
  7. #pragma region 定义堆的存储结构
  8. typedef int HeapDataType;
  9. /*定义哨兵*/
  10. #define MAXDATA 0xfffff
  11. typedef struct HNode* heap;
  12. typedef heap MaxHeap;/*MaxHeap==Heap==HNode 所以MaxHeap是指针类型*/
  13. typedef struct HNode
  14. {
  15. HeapDataType* HeadData;/*指针用来指向数据存储的空间*/
  16. int sizes;/*当前堆的存储的数据的个数*/
  17. int capacity;/*堆所满足的最大的容量*/
  18. };
  19. #pragma endregion
  20. /*堆的创建*/
  21. MaxHeap/*此时实际上返回的是HNode*/ CreatHeap(int MaxSize);
  22. /*堆的销毁*/
  23. void DestoryHeap(MaxHeap M_hp);
  24. /*堆的插入*/
  25. MaxHeap InsertHeap(MaxHeap Mhp, HeapDataType* item);
  26. /*堆的删除*/
  27. MaxHeap DeleteHeap(MaxHeap Mhp);
  28. /*创建最大堆*/
  29. void MoveDown(MaxHeap Mhp, int length);
  30. /*判断堆是否已满*/
  31. bool IsFull(MaxHeap Mhp);

堆的具体实现的CPP程序

  1. #include"Heap.h"
  2. /*创建具有MaxSize容量的最大堆*/
  3. MaxHeap/*此时实际上返回的是HNode*/ CreatHeap(int MaxSize)
  4. {
  5. MaxHeap Heap = NULL;
  6. Heap = (MaxHeap)malloc(sizeof(HNode));
  7. Heap->HeadData = (HeapDataType*)malloc(sizeof(HNode)*(MaxSize + 1));
  8. Heap->capacity = MaxSize;
  9. Heap->sizes = 0;
  10. Heap->HeadData[0] = MAXDATA;
  11. return Heap;
  12. }
  13. #pragma region 销毁最大堆
  14. void DestoryHeap(MaxHeap Mhp)
  15. {
  16. if (Mhp == NULL)
  17. {
  18. return;
  19. }
  20. delete[] Mhp->HeadData;
  21. Mhp->HeadData = NULL;
  22. Mhp->capacity = 0;
  23. Mhp->sizes = 0;
  24. }
  25. #pragma endregion
  26. #pragma region 最大堆元素的插入
  27. void SWAP(HeapDataType item_1, HeapDataType item_2)
  28. {
  29. HeapDataType tmpstore;
  30. tmpstore = item_1;
  31. item_1 = item_2;
  32. item_2 = item_1;
  33. }
  34. MaxHeap InsertHeap(MaxHeap Mhp, HeapDataType* item)
  35. {
  36. if (Mhp == NULL || item == NULL)
  37. {
  38. return false;/*输入的数据不符合要求*/
  39. }
  40. MaxHeap tmphp = NULL;
  41. tmphp = Mhp;
  42. /*判断是否满了*/
  43. if (tmphp->sizes == tmphp->capacity)
  44. {
  45. cout << "该堆结构存储空间已满" << endl;
  46. return false;
  47. }
  48. tmphp->HeadData[tmphp->sizes + 1] = *item;/*将元素首先放在尾部*/
  49. int childPos = tmphp->sizes + 1;
  50. int parentPos = childPos / 2;
  51. while (tmphp->HeadData[childPos] > tmphp->HeadData[parentPos])/*证明插入数据大于根节点的数据*/
  52. {
  53. SWAP(tmphp->HeadData[childPos], tmphp->HeadData[parentPos]);
  54. childPos = parentPos;
  55. parentPos = childPos / 2;
  56. }
  57. tmphp->sizes++;
  58. return tmphp;
  59. }
  60. #pragma endregion
  61. #pragma region 最大堆元素的删除
  62. MaxHeap DeleteHeap(MaxHeap Mhp)
  63. {
  64. if (Mhp == NULL || Mhp->sizes == 0)
  65. {
  66. cout << "堆为空" << endl;
  67. return NULL;
  68. }
  69. MaxHeap tmphp = NULL;
  70. tmphp = Mhp;
  71. int parent = 1;
  72. int child = 2 * parent + 1;
  73. while (child<=tmphp->sizes)
  74. {
  75. if ((child+1<=tmphp->sizes)/*右孩子存在*/ && (tmphp->HeadData[child]<tmphp->HeadData[child+1]/*选择孩子中的最大一个*/) )
  76. {
  77. child = child + 1;/*先找到符合条件的child的位置*/
  78. }
  79. /*交换*/
  80. if (tmphp->HeadData[parent]<tmphp->HeadData[child])
  81. {
  82. SWAP(tmphp->HeadData[parent], tmphp->HeadData[child]);
  83. parent = child;
  84. child = 2 * parent + 1;
  85. }
  86. else
  87. {
  88. break;
  89. }
  90. }
  91. tmphp->sizes--;
  92. return tmphp;
  93. }
  94. #pragma endregion
  95. #pragma region 创建最大堆
  96. void MoveDown(MaxHeap Mhp, int length)
  97. {
  98. if (Mhp == NULL || length == 0)
  99. {
  100. cout << "输入的堆的元素为空" << endl;
  101. return;
  102. }
  103. MaxHeap tmphp = NULL;
  104. tmphp = Mhp;
  105. int parent = length;
  106. int child = 2 * length + 1;
  107. while (child <=tmphp->sizes)/*防止左孩子出界*/
  108. {
  109. if ((child+1<=tmphp->sizes) && (tmphp->HeadData[child]<=tmphp->HeadData[child+1]))
  110. {
  111. /*右孩子更大*/
  112. child = child + 1;/*将更换的位置调整为右孩子*/
  113. }
  114. /*判断父结点位置的元素是否比孩子结点的小*/
  115. if (tmphp->HeadData[parent]<tmphp->HeadData[child])
  116. {
  117. SWAP(tmphp->HeadData[parent], tmphp->HeadData[child]);
  118. parent = child;
  119. child = 2 * parent + 1;
  120. }
  121. else
  122. {
  123. break;
  124. }
  125. }
  126. }
  127. MaxHeap CreatMaxHeap(MaxHeap Mhp)
  128. {
  129. int length = Mhp->sizes/2;
  130. MaxHeap tmphp = NULL;
  131. tmphp = Mhp;
  132. /*首先找到具有最后一个结点的孩子*/
  133. for (length;length>0;length--)
  134. {
  135. MoveDown(tmphp, length);
  136. }
  137. return tmphp;
  138. }
  139. #pragma endregion
  140. #pragma region 判断堆满情况
  141. bool IsFull(MaxHeap Mhp)
  142. {
  143. if (Mhp->sizes == Mhp->capacity)
  144. {
  145. return true;
  146. }
  147. return false;
  148. }
  149. #pragma endregion

这里需要明确:给定一组数据,利用大根堆的方式存储,具体步骤:

  • > 首先寻找到具有最后一个顺序存储的叶子结点的父亲结点,开始实现自后向前的遍历
  • 遍历的每一个结点都实现基于大根堆的大数据向上移动而小数据向下move down的策略 。所以,有了一种针对每个结点都重复一次操作的实现过程。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/90473
推荐阅读
相关标签
  

闽ICP备14008679号