堆类似一颗完全二叉树,根节点是一个最值,同时它的左右两颗子树也是堆。下面以最大堆为例,插入操作跟插入排序是一样的,把新加入的节点放到树的最后面,然后跟它的父亲比较,如果比父亲比它小,则互换位置,直到找到某个祖先节点大于它时停止。取最大值则直接取根节点,若删去该节点,则要重新调整堆,使得该堆仍是最大堆。做法是把树中最后一个节点放到根节点,然后向下查找,跟其值最小的孩子互换位置,直到找到一个大于它的子孙节点便终止。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cstdlib>
using namespace std;
void update_down(int *heap,int pos,int sum)
{
int tem = heap[pos];
int son = pos<<1;
while(son <= sum)
{
if(son < sum && heap[son] < heap[son+1])
son++;
if(heap[son] > tem)
{
heap[pos] = heap[son];
pos = son, son = pos<<1;
}
else
break;
}
heap[pos] = tem;
}
void update_up(int *heap,int pos,int sum)
{
int tem = heap[pos];
int father = pos>>1;
while(father > 0 && heap[father] < tem)
{
heap[pos] = heap[father];
pos = father, father = pos>>1;
}
heap[pos] = tem;
}
int main()
{
int len, *heap;
cin >> len;
heap = new int [len+1];
srand((int)time(0));
int startTime = clock();
for(int i=1; i<=len; i++)
{
heap[i] = rand()%512 + 1;
update_up(heap,i,i);
}
int sum = len;
while(sum)
{
// cout << heap[1] << " ";
heap[1] = heap[sum--];
update_down(heap,1,sum);
}
int endTime = clock();
cout << "\nused time: " << endTime - startTime << endl;
}