Heap.h
/堆类
#pragma once
#include<iostream>
using namespace std;
#include<vector>
#include<assert.h>
//仿函数(函数对象)--建小堆
template<typename T>
struct Less
{
bool operator()(const T& left, const T& right)
{
return left<right;
}
};
//仿函数(函数对象)--建大堆
template<typename T>
struct Great
{
bool operator()(const T& left, const T& right)
{
return left>right;
}
};
template<typename T, typename Compare>
class Heap
{
public:
Heap()//默认构造函数(全缺省构造函数)
{}
Heap(const T* arr, size_t sz)//构造函数
{
assert(arr);
//1.将数组中的元素放入堆中
for (int i = 0; i<sz; ++i)
{
_heap.push_back(arr[i]);
}
//2.从堆中(sz-2)/2的位置(即最后一个非叶子节点位置)开始利用向下调整建堆
for (int i = (sz - 2) / 2; i >= 0; ++i)
{
AdjustDown(i);
}
}
void Push(const T& x)//插入--插入到最后一个位置,然后沿着该节点到根结点的路径向上调整
{
_heap.push_back(x);
AdjustUp(_heap.size() - 1);
}
void Pop()//删除(堆顶元素)---将堆顶元素和堆底元素交换;删除堆底元素;然后从堆顶向下调整
{
if (_heap.empty())
{
cout << "heap empty" << endl;
}
else
{
//先交换堆底和堆顶元素
std::swap(_heap[0], _heap[_heap.size() - 1]);
_heap.pop_back();
//然后从堆顶开始向下调整
AdjustDown(0);
}
}
const T& Top()//取最值(堆顶元素)
{
if (!_heap.empty())
{
return _heap[0];
}
else
{
cout << "heap empty!" << endl;
}
}
size_t Size()//返回堆中元素个数
{
return _heap.size();
}
bool Empty()//判断堆是否为空
{
return _heap.empty();
}
private:
//向下调整
void AdjustDown(size_t index)
{
size_t leftchild = index * 2 + 1;//左孩子
Compare com;//大小堆
while (leftchild<_heap.size())
{
//1.寻找左右孩子的最值下标
if (leftchild + 1<_heap.size() && com(_heap[leftchild + 1], _heap[leftchild]))
{
leftchild++;//记录左右孩子的最值下标
}
//2.比较并决定是否交换
//2.1 交换,继续向下调整
if (com(_heap[leftchild], _heap[index]))
{
std::swap(_heap[leftchild], _heap[index]);
//继续向下调整
index = leftchild;
leftchild = index * 2 + 1;
}
//2.2不交换,那么不用继续向下调整
else
break;
}
}
//向上调整
void AdjustUp(int index)
{
int father = (index - 2) / 2;//父节点
Compare com;
while (father >= 0)
{
//交换,继续向上调整
if (com(_heap[index], _heap[father]))
{
std::swap(_heap[index], _heap[father]);
index = father;
father = (index - 2) / 2;//继续向上调整
}
//不交换,不用向上调整
else
break;
}
}
private:
vector<T> _heap;
};
HuffmanTree.h
//哈夫曼树类
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
#in