好久没看最小堆了,突然上手写半天还反应不过来。手动写一下,顺便贴上代码:
手动实现:
#include<iostream>
using namespace std;
const int MAXN = 1000;
template<typename T>
class minHeap
{
private:
int size;
T data[MAXN + 1];
void shiftDown(int pos);
void shiftUp(int pos);
public:
minHeap();
void makeHeap(T* items, int num);
void add(T item);
T pop();
int getSize();
bool empty();
void clear();
};
template<typename T>
minHeap<T>::minHeap()
{
size = 0;
}
template<typename T>
void minHeap<T>::makeHeap(T* items, int num)
{
clear();
//不断插入构建最小堆
for(int i = 0; i < num; ++i)
add(items[i]);
clear();
//从第一个非叶节点开始调整堆
size = num;
for(int i = 1; i <= num; ++i)
data[i] = items[i - 1];
for(int i = size>>1; i> 0; --i)
shiftDown(i);
}
template<typename T>
void minHeap<T>::shiftDown(int pos)
{
if(pos<<1 > size)
return;
int left = pos<<1;
int right = left + 1;
int minPos = left;
if(right <= size && data[right] < data[left])
minPos = right;
if(data[minPos] < data[pos])
{
swap(data[minPos], data[pos]);
shiftDown(minPos);
}
}
template<typename T>
void minHeap<T>::shiftUp(int pos)
{
if(pos <= 0)
return;
int parent = pos>>1;
if(data[pos] < data[parent])
{
swap(data[pos], data[parent]);
shiftUp(parent);
}
}
template<typename T>
void minHeap<T>::add(T item)
{
if(size == MAXN)
{
cout<<"Failed to add "<<item<<" ! The heap is full!"<<endl;
return;
}
data[++size] = item;
shiftUp(size);
}
template<typename T>
T minHeap<T>::pop()
{
if(size == 0)
{
cout<<"Failed to pop the heap! The heap is empty!"<<endl;
return NULL;
}
T t = data[1];
data[1] = data[size--];
shiftDown(1);
return t;
}
template<typename T>
int minHeap<T>::getSize()
{
return size;
}
template<typename T>
bool minHeap<T>::empty()
{
return (size > 0);
}
template<typename T>
void minHeap<T>::clear()
{
size = 0;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
minHeap<int> heap;
int m;
int items[10];
cin>>m;
for(int i = 0; i < m; ++i)
{
cin>>items[i];
//heap.add(items[i]);
}
heap.makeHeap(items, 10);
cout<<"heap size is "<<heap.getSize()<<endl;
for(int i = 0; i < m; ++i)
{
int item = heap.pop();
cout<<item<<" ";
}
cout<<endl;
return 0;
}
STL实现:
建堆:make_heap(_First, _Last, _Comp)
默认是建立最大堆的。对int类型,可以在第三个参数传入greater<int>()得到最小堆。
在堆中添加数据:push_heap (_First, _Last)
要先在容器中加入数据,再调用push_heap ()
在堆中删除数据:pop_heap(_First, _Last)
要先调用pop_heap()再在容器中删除数据
堆排序:sort_heap(_First, _Last)
排序之后就不再是一个合法的heap了
注意:sort_heap 第三个参数必须和堆结构对应,否则会出现错误!!比如为最小堆时,sort_heap参数必须为greater<int>(),得到的排序为从大到小;为最大堆时,参数缺省或者为less<int>(),得到的排序为从小到大。这是因为sort_heap实际就是一直在做pop,把堆顶的元素交换到最后。
#include<iostream>
#include<algorithm>
#include<functional>
#include<vector>
using namespace std;
void printItem(vector<int> items)
{
for(vector<int>::iterator it = items.begin(); it != items.end(); ++it)
cout<<*it<<" ";
cout<<endl;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int numbers[] = {5,6,22,33,4,1,7,12,8,13};
vector<int> items(numbers, numbers + 10);
cout<<"---------make heap-----------"<<endl;
make_heap(items.begin(), items.end(), greater<int>());//第三个参数缺省或者是less<int>()时 为最大堆
printItem(items);
cout<<"---------push heap-----------"<<endl;
items.push_back(0);
push_heap(items.begin(), items.end(), greater<int>());
printItem(items);
cout<<"---------pop heap-----------"<<endl;
pop_heap(items.begin(), items.end(), greater<int>());
items.pop_back();
printItem(items);
cout<<"---------sort heap-----------"<<endl;
sort_heap(items.begin(), items.end(), greater<int>());
printItem(items);
return 0;
}