堆
- 堆是一种二叉树,完全二叉树(结点依次排列),不完全二叉树(结点间有间隔);
- 使用数组
- 大顶堆,小顶堆
- 二叉树可以和数组对应转换,根据情况具体选择。
- 堆的操作:插入,删除,堆都可以满足堆的定义。
- 插入新节点->向上渗透,将一个元素插到最后,然后将其向上渗透,进行调整。
- 删除根节点->向下渗透,删除根节点,将最后一个元素放到很节点,然后将其向下渗透,进行调整。
- 子节点与父节点:(n-1)/2,子节点n的父节点位置;2n+1,2n+2,父节点n的左子节点2n+1,右子节点2n+2;
#pragma once
#ifndef _HEAP_
#define _HEAP_
template<class T>
class Heap_Max
{
public:
Heap_Max(int length = 10);
virtual ~Heap_Max();
bool IsEmpty();
void Push(const T&);
void up(int); //向上渗透,进行调整
void down(int);//向下渗透,进行调整
const T& Top() const;
void pop();
private:
T* HeapArray;
int maxSize;
int currentSize;
};
#endif // !_HEAP_
template<class T>
inline Heap_Max<T>::Heap_Max(int length=10)
{
if (length <= 0) cout << "max size error" << endl;
maxSize = length;
currentSize = 0;
HeapArray = new T[maxSize];
}
template<class T>
inline Heap_Max<T>::~Heap_Max()
{
delete[] HeapArray;
}
template<class T>
inline bool Heap_Max<T>::IsEmpty()
{
return currentSize == 0;
}
template<class T>
inline void Heap_Max<T>::Push(const T & e)
{
if (currentSize == maxSize) cout << "heap is full";//可以使用抛出异常
HeapArray[currentSize] = e;
up(currentSize);//向上渗透
currentSize++;
}
template<class T>
inline void Heap_Max<T>::up(int pos)
{
int parent = (pos - 1) / 2;
T temp = HeapArray[pos];
while (pos>0&&HeapArray[parent]<temp)//大顶堆,父节点值大于子节点
{
HeapArray[pos] = HeapArray[parent];
pos = parent;
parent = (parent - 1) / 2;
}
HeapArray[pos] = temp;
}
template<class T>
inline const T & Heap_Max<T>::Top() const
{
return HeapArray[0];
}
template<class T>
inline void Heap_Max<T>::pop()
{
currentSize--;
HeapArray[0] = HeapArray[currentSize];//覆盖根,即删除了根,在调整
down(0);
}
template<class T>
inline void Heap_Max<T>::down(int pos)
{
int max;
T top = HeapArray[pos];
while(pos<currentSize/2)
{
int lchild= 2 * pos + 1;
int rchild = lchild + 1;
if (rchild < currentSize&&HeapArray[lchild] < HeapArray[rchild])
max = rchild;
else
max = lchild;
if (top >= HeapArray[max])
break;
HeapArray[pos] = HeapArray[max];
pos = max;
}
HeapArray[pos] = top;
}