当前位置:   article > 正文

【数据结构】实现大小堆也叫二叉堆(类似c++中的优先队列)_二叉堆c语言链表实现

二叉堆c语言链表实现

二叉堆:

是一种特殊的堆,依赖于完成完全二叉树和向量实现的。分为最大堆和最小堆。



最大堆:父节点的键值总是大于或等于任何一个子节点的键值。


最小堆:父节点的键值总是小于或等于任何一个子节点的键值。



存储:二叉树一般用数组来存储表示,在下面的实现中使用了STL中的vector。根节点在数组中的位置是0,第n个位置的左孩子下标为n*2+1,右孩子为2*n+2 ,当前孩子存在的前提是计算后下标要小于数组总个数。而用孩子结点的下标c,可以计算出双亲的下标(c-1)/2。


基本操作:可以进行插入结点,移除最小的结点,和返回最小的结点,返回当前堆中元素个数。


代码:这个是用模板参数实现,传入函数对象生成大小堆,默认小堆:

  1. #ifndef _HEAP_H_
  2. #define _HEAP_H_
  3. #include <cassert>
  4. #include <vector>
  5. #include <iostream>
  6. using namespace std;
  7. // 仿函数小堆调用
  8. template <class T>
  9. class Less
  10. {
  11. public:
  12. bool operator()(const T& left, const T& right)
  13. {
  14. return left <= right;
  15. }
  16. };
  17. // 仿函数大堆调用
  18. template <class T>
  19. class Greater
  20. {
  21. public:
  22. bool operator()(const T& left, const T& right)
  23. {
  24. return left > right;
  25. }
  26. };
  27. // 模板参数的大小堆
  28. template <class T, class Compare = Less<T>>
  29. class Heap
  30. {
  31. public:
  32. Heap(){}
  33. Heap(const T arr[] , int size)
  34. {
  35. for (int i=0; i<size; ++i)
  36. {
  37. _heap.push_back(arr[i]);
  38. }
  39. int last = (size - 2)/2;
  40. for (int i=last; last>=0; --last)
  41. {
  42. _AdjustDown(last, size);
  43. }
  44. }
  45. void Insert(const T data)
  46. {
  47. _heap.push_back(data);
  48. _AdjustUp(_heap.size());
  49. }
  50. T& Top()
  51. {
  52. assert(!_heap.empty());
  53. return _heap[0];
  54. }
  55. const T& Top()const
  56. {
  57. assert(!_heap.empty());
  58. return _heap[0];
  59. }
  60. void Remove()
  61. {
  62. int size = _heap.size();
  63. if (size > 1)
  64. {
  65. std::swap(_heap[0], _heap[size-1]);
  66. _heap.pop_back();
  67. _AdjustDown(0, _heap.size());
  68. }
  69. else
  70. {
  71. _heap.pop_back();
  72. }
  73. }
  74. private:
  75. void _AdjustUp(int size)
  76. {
  77. int child = size - 1;
  78. int parent = (child-1)/2;
  79. while (child != 0)
  80. {
  81. // 孩子小于父亲
  82. if (Compare()(_heap[child], _heap[parent]))
  83. {
  84. std::swap(_heap[child], _heap[parent]);
  85. child = parent;
  86. parent = (child - 1 )/2;
  87. }
  88. else
  89. {
  90. break;
  91. }
  92. }
  93. }
  94. void _AdjustDown(int root, int size)
  95. {
  96. int child = root*2 + 1;
  97. int parent = root;
  98. while (child < size)
  99. {
  100. if (child+1 < size && Compare()(_heap[child+1], _heap[child]) )
  101. {
  102. child += 1;
  103. }
  104. // 小 less
  105. if (Compare()(_heap[child], _heap[parent]))
  106. {
  107. std::swap(_heap[child], _heap[parent]);
  108. parent = child;
  109. child = child *2 + 1;
  110. }
  111. else
  112. {
  113. break;
  114. }
  115. }
  116. }
  117. private:
  118. vector<T> _heap;
  119. };
  120. #endif _HEAP_H_

这个是用模板的模板参数实现:

  1. #ifndef _HEAP_H_
  2. #define _HEAP_H_
  3. #include <cassert>
  4. #include <vector>
  5. #include <iostream>
  6. using namespace std;
  7. // 仿函数小堆调用
  8. template <class T>
  9. class Less
  10. {
  11. public:
  12. bool operator()(const T& left, const T& right)
  13. {
  14. return left <= right;
  15. }
  16. };
  17. // 仿函数大堆调用
  18. template <class T>
  19. class Greater
  20. {
  21. public:
  22. bool operator()(const T& left, const T& right)
  23. {
  24. return left > right;
  25. }
  26. };
  27. // 模板的模板参数 大小堆
  28. template<class T, template<class> class Compare = Less>
  29. class Heap
  30. {
  31. public:
  32. Heap(){}
  33. Heap(const T arr[], int size)
  34. {
  35. for (int i=0; i<size; ++i)
  36. {
  37. _heap.push_back(arr[i]);
  38. }
  39. int root = (size - 2)/2;
  40. for (int i=root; i>=0; --i)
  41. {
  42. _AdjustDown(i, size);
  43. }
  44. }
  45. void Insert(const T& data)
  46. {
  47. _heap.push_back(data);
  48. _AdjustUp(_heap.size());
  49. }
  50. void Remove()
  51. {
  52. if (!_heap.empty())
  53. {
  54. if (_heap.size()>1)
  55. {
  56. std::swap(_heap[0], _heap[_heap.size()-1]);
  57. _heap.pop_back();
  58. _AdjustDown(0, _heap.size());
  59. }
  60. else
  61. {
  62. _heap.pop_back();
  63. }
  64. }
  65. }
  66. T& Top()
  67. {
  68. assert(!_heap.empty());
  69. return _heap[0];
  70. }
  71. const T& Top()const
  72. {
  73. assert(!_heap.empty());
  74. return _heap[0];
  75. }
  76. private:
  77. void _AdjustUp(int size)
  78. {
  79. int child = size-1;
  80. int parent= (child-1)/2;
  81. while (child != 0)
  82. {
  83. if (Compare<T>()(_heap[child], _heap[parent]))
  84. {
  85. std::swap(_heap[child], _heap[parent]);
  86. child = parent;
  87. parent = (child-1)/2;
  88. }
  89. else
  90. {
  91. break;
  92. }
  93. }
  94. }
  95. void _AdjustDown(int root, int size)
  96. {
  97. int parent = root;
  98. int child = root*2 + 1;
  99. while (child < size)
  100. {
  101. if (child+1 < size && Compare<T>()(_heap[child+1],_heap[child]) )
  102. {
  103. child = child+1;
  104. }
  105. if (Compare<T>()(_heap[child], _heap[parent]))
  106. {
  107. std::swap(_heap[child], _heap[parent]);
  108. parent = child;
  109. child = child*2 + 1;
  110. }
  111. else
  112. {
  113. break;
  114. }
  115. }
  116. }
  117. private:
  118. vector<T> _heap;
  119. };
  120. #endif _HEAP_H_



本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号