堆
- 性质: 1.堆是一颗完全二叉树,用数组实现。
2.堆中存储数据的数据是局部有序的。 - 最大堆:1.任意一个结点存储的值都大于或等于其任意一个子结点中存储的值。
2.根结点存储着该树所有结点中的最大值。 - 最小堆:1.任意一个结点存储的值都小于或等于其惹你一个子结点存储的值。
2.根结点存储着该树所有结点中的最小值。 - 无论最小堆还是最大堆,任何一个结点与其兄弟结点之间都没有必然联系。
- 以下给出最大堆的类声明及其成员函数的实现:
template<typename E> class heap{
private:
E* Heap;
int maxsize;
int n;
void siftdown(int pos)
{
while (!isLeaf(pos))
{
int j = leftchild(pos);
int rc = rightchild(pos);
if ((rc < n)&& prior(Heap[rc], Heap[j]))
j = rc;
if (prior(Heap[pos], Heap[j])) return;
swap(Heap, pos, j);
pos = j;
}
}
public:
heap(E* h, int num, int max)
{
Heap = h; n = num; maxsize = max;
buildHeap();
}
int size() const
{return n;}
bool isLeaf(int pos) const
{
return (pos >= n / 2) && (pos < n);
}
int leftchild(int pos) const
{
return 2 * pos + 1;
}
int rightchild(int pos) const
{
return 2 * pos + 2;
}
int parent(int pos) const
{
return (pos - 1) / 2;
}
void buildHeap()
{
for (int i = n / 2 - 1; i >= 0; i--) siftdown(i);
}
void insert(const E& it)
{
assert(n < maxsize, "Heap is full");
int curr = n++;
Heap[curr] = it;
while ((curr != 0) && (prior(Heap[curr], Heap[parent(curr)])))
{
swap(Heap, curr, parent(curr));
curr = parent(curr);
}
}
E removefirst()
{
assert(n > 0, "Heap is empty");
swap(Heap, 0, --n);
if (n != 0)siftdown(0);
return Heap[n];
}
E remove(int pos)
{
assert((pos >= 0)&&(pos < n), "Bad position");
if (pos == (n - 1)) n--;
else
{
swap(Heap, pos, --n);
while ((pos) != 0 && (prior(Heap[pos], Heap[parent(pos)])))
{
swap(Heap, pos, parent(pos));
pos = parent(pos);
}
if (n != 0) siftdown(pos);
}
return Heap[n];
}
bool prior(E a, E b)
{
if (a > b) return true;
else return false;
}
void swap(E* heap, int i, int j)
{
E temp;
temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
void print()
{
for (int i = 0; i < n; i++)
{
cout << Heap[i] << " ";
}
cout << endl<<endl;
}
};