堆的插入在这里: 堆的插入.
下沉法
下沉法与堆插入方法中的上移法对应,首先将堆尾的元素赋值给堆首的元素,然后在从上往下依次判断父节点和子节点的大小关系,如果父节点比子节点要大(构造最小堆),就交换父子节点的值。
int Delete()
{
if (len < 1)
{
printf("堆为空\n");
return -1;
}
else
{
int h = heap[1];
heap[1] = heap[len--];
int fa = 1;
int son = 2 * fa;
while (son <= len)
{
if (heap[son] > heap[son + 1])
{
son += 1;
}
if (heap[fa] < heap[son])
{
break;
}
swap(heap[son], heap[fa]);
fa = son;
son = 2 * fa;
}
return h;
}
}
上移法
int Delete()
{
if (len < 1)
{
printf("堆为空\n");
return -1;
}
else
{
int t = heap[len--];
int h = heap[1];
int fa = 1;
int son = 2 * fa;
while (son <= len)
{
if (heap[son] > heap[son + 1])
{
son += 1;
}
if (heap[son] > t)
{
break;
}
heap[fa] = heap[son];
fa = son;
son = fa * 2;
}
heap[fa] = t;
return h;
}
}
完整测试代码:
#include<iostream>
using namespace std;
const int maxn = 200 + 5;
int len = 0;
int heap[maxn];
void insert(int value)//哨兵法插入
{
if (len >= maxn)
{
printf("堆已满\n");
return;
}
else
{
int son = ++len;
int fa = son / 2;
heap[0] = -INT_MAX;
while (value < heap[fa])
{
heap[son] = heap[fa];
son = fa;
fa = son / 2;
}
heap[son] = value;
}
}
int Delete()
{
if (len < 1)
{
printf("堆为空\n");
return -1;
}
else
{
int h = heap[1];
heap[1] = heap[len--];
int fa = 1;
int son = 2 * fa;
while (son <= len)
{
if (heap[son] > heap[son + 1])
{
son += 1;
}
if (heap[fa] < heap[son])
{
break;
}
swap(heap[son], heap[fa]);
fa = son;
son = 2 * fa;
}
return h;
}
}
void show(void)
{
for (int i = 1; i <= len; i++)
{
printf("%d ", heap[i]);
}
printf("\n");
}
int main(void)
{
insert(3);
insert(4);
insert(5);
insert(7);
insert(6);
insert(1);
show();
for (int i = 0; i < 6; i++)
{
printf("%d ", Delete());
}
return 0;
}