大根堆是一种树形的结构,所有父结点都大于子结点,一般用一维数组表示,若父结点下标为n (开始下标从0开始),则左孩子下标为 2n+1.右孩子为2n+2
- 堆数据使用STL向量vector保存
- 容量vector自动扩充
- 头文件如下
#pragma once
#include<vector>
template <class T>
class MaxHeap
{
public:
MaxHeap(size_t capacity = 10);
~MaxHeap();
bool IsEmpty() const;
void Push(const T&);
void Pop();
const T& Top() const;
size_t Size() const;
private:
std::vector<T>* m_heap; //保存数据的一维数组
size_t m_size;
void __insertFix(int);
void __deletetFix(int);
};
template<class T>
inline MaxHeap<T>::MaxHeap(size_t capacity)
: m_size(0)
{
m_heap = new std::vector<T>(capacity);
}
template<class T>
inline MaxHeap<T>::~MaxHeap()
{
delete m_heap;
}
template<class T>
inline bool MaxHeap<T>::IsEmpty()const
{
return m_size == 0;
}
template<class T>
inline void MaxHeap<T>::Push(const T& item)
{
if (m_size == m_heap->size())
{
m_heap->resize(2 * m_size);
}
m_heap->at(m_size) = item; //插入最后一个元素
__insertFix(m_size++);
}
template<class T>
inline void MaxHeap<T>::Pop()
{
if (IsEmpty())
{
throw "堆为空";
}
//m_heap->at(0).~T();
//m_heap->at(0) = m_heap->at(--m_size);
std::swap(m_heap->at(0), m_heap->at(m_size - 1)); //最后一个元素与第一个交换
m_heap->at(--m_size).~T(); //删除最后元素
__deletetFix(0);
}
template<class T>
inline const T& MaxHeap<T>::Top() const
{
if (IsEmpty())
{
throw "堆为空";
}
return m_heap->at(0);
}
template<class T>
inline size_t MaxHeap<T>::Size() const
{
return m_size;
}
template<class T>
inline void MaxHeap<T>::__insertFix(int index)
{
//向上渗透修复
int parent = (index - 1) / 2; //父结点
T temp = m_heap->at(index); //保存插入结点数据
while (index > 0 && temp > m_heap->at(parent))
{
m_heap->at(index) = m_heap->at(parent);
index = parent;
parent = (parent - 1) / 2;
}
m_heap->at(index) = temp;
}
template<class T>
inline void MaxHeap<T>::__deletetFix(int index)
{
//向下渗透修复
T temp = m_heap->at(index); //保存最后结点数据(已经放置堆顶)
int maxChild;
while (index < m_size / 2) //至倒数第二层
{
int left = index * 2 + 1; //左孩子
int right = left + 1; //右孩子
//找最大的孩子
if (right < m_size && m_heap->at(left) < m_heap->at(right))
{
maxChild = right;
}
else
{
maxChild = left;
}
//已找到合适位置,当前结点(maxChild的父亲)
if (temp > m_heap->at(maxChild))
{
break;
}
m_heap->at(index) = m_heap->at(maxChild);
index = maxChild;
}
//覆盖
m_heap->at(index) = temp;
}
- 测试用例
#include<iostream>
#include <time.h>
#include <vector>
#include <list>
#include"maxHeap.h"
using namespace std;
void test()
{
MaxHeap<int> h;
int a[] = { 10, 40, 30, 60, 90, 70, 20, 50, 80 };
for (size_t i = 0; i < 9; i++)
{
h.Push(a[i]);
}
while (!h.IsEmpty())
{
cout << h.Top() << " size: " << h.Size() << endl;
h.Pop();
}
}
void main() {
test();
}