二叉堆: 堆是一颗完全二叉树, 即除了底层外都被填满,底层从左到右填入的二叉树,注意不是满二叉树;
堆的特性:最大堆,堆顶元素始终为最大值,任一节点的左右儿子则均小于该节点,最小堆则相反
堆由于其特性可以以数组实现并且不大量浪费空间;
当该节点为位置为i时,其左儿子位置为2i, 右儿子为2i+1;
root节点应在下标为1的位置;
这里实现了最大堆
/***********************************************
> Filename: Heap.cpp
> Author: Pyt
> Create: 2017-08-04 16:19:49
************************************************/
#include <iostream>
#include <vector>
using namespace std;
template<typename T>
class Heap{
public:
Heap();
explicit Heap(const vector<T> &t);
T top() const;
void push(const T &t);
void pop();
bool empty() const;
private:
vector<T> tree;
size_t cursize;
void buildHeap();
void percolateDown(int hole);
};
/***默认构造****/
template<typename T>
Heap<T>::Heap()
: tree(100), cursize(0)
{
}
/****vector建堆****/
template<typename T>
Heap<T>::Heap(const vector<T> &t)
: tree(t.size()+10), cursize(t.size())
{
for(int i=0; i<t.size(); i++)
tree[i+1] = t[i];
buildHeap();
}
/***返回堆顶元素****/
template<typename T>
T Heap<T>::top() const
{
if(!empty())
return tree[1];
}
/****插入元素*****/
template<typename T>
void Heap<T>::push(const T &t)
{
if(cursize == tree.size()-1)
tree.resize(tree.size()*2);
size_t hole = ++cursize;
for(; hole>1 && tree[hole/2]<t; hole /= 2)
tree[hole] = tree[hole/2];
tree[hole] = t;
}
/****删除堆顶元素****/
template<typename T>
void Heap<T>::pop()
{
if(empty())
return ;
T tmp = tree[cursize--];
tree[1] = tmp;
percolateDown(1);
}
/***判空****/
template<typename T>
bool Heap<T>::empty() const
{
return cursize == 0;
}
/****私有函数将无序数组建堆****/
template<typename T>
void Heap<T>::buildHeap()
{
for(int i=cursize/2; i>=1; i--)
percolateDown(i);
}
/***私有函数下滤*****/
template<typename T>
void Heap<T>::percolateDown(int hole)
{
T tmp = tree[hole];
int child;
for( ; hole*2 <= cursize; hole = child)
{
child = hole*2;
if(child!=cursize && tree[child+1]>tree[child])
child++;
if(tree[child] > tmp)
tree[hole] = tree[child];
else
break;
}
tree[hole] = tmp;
}
int main()
{
vector<int> a = {5, 2, 1, 7, 4, 3, 9, 8};
Heap<int> q(a);
Heap<int> p;
p = q;
while(!p.empty())
{
cout << p.top() << endl;
p.pop();
}
cout << p.empty() << endl;
}