堆的基本操作——基于数组实现
SiftUp
void siftUp(int i)
{
bool done = false;
if(i==1) return;//根节点,无法上移
while(true)
{
if(h[i]>h[i/2])
{
int temp = h[i];
h[i] = h[i/2];
h[i/2] = temp;
}
else
done = true;
i/=2;
if(done || i==1 || i==0) break;//忽略i==0
}
}
siftDown
void siftDown(int i)//i为索引,n为数组元素个数
{
bool done = false;
if(2*i>n) return;
while(true)
{
i*=2;
if(i+1<=n&&h[i+1]>h[i]) i+=1;//取左右孩子中最大的那一个
if(h[i/2]<h[i])
{
int temp = h[i];
h[i] = h[i/2];
h[i/2] = temp;
}
else done = true;
if(done || 2*i>n) break;
}
}
insert
void insert(int x)
{
n = n+1;
h[n] = x;
siftUp(n);
}
delete
void del(int i)
{
int x = h[i];
int y = h[n];
n = n-1;
if(i=n+1) return;
h[i] = y;
if(y>x) siftUp(i);
else siftDown(i);
}
makeHeap
void makeHeap()
{
for(int i=n/2;i>=1;i++)
siftDown(i);
}
全部代码
#include<iostream>
using namespace std;
int h[1005];//数组
int n;//元素个数
void siftUp(int i)
{
bool done = false;
if(i==1) return;//根节点,无法上移
while(true)
{
if(h[i]>h[i/2])
{
int temp = h[i];
h[i] = h[i/2];
h[i/2] = temp;
}
else
done = true;
i = i/2;
if(i==1 ||i==0 || done) break;
}
}
void siftDown(int i)//i为索引
{
bool done = false;
if(2*i>n) return;
while(true)
{
i = 2*i;
if(i+1<=n&&h[i+1]>h[i]) i+=1;//取左右孩子中最大的那一个
if(h[i/2]<h[i])
{
int temp = h[i];
h[i] = h[i/2];
h[i/2] = temp;
}
else done = true;
if(done ||2*i>n) break;
}
}
void insert(int x)
{
n = n+1;
h[n] = x;
siftUp(n);
}
void del(int i)
{
int x = h[i];
int y = h[n];
n = n-1;
if(i=n+1) return;
h[i] = y;
if(y>x) siftUp(i);
else siftDown(i);
}
void makeHeap()
{
for(int i = n/2;i>=1;i--)
siftDown(i);
}
void print()
{
for(int i=1;i<=n;i++)
cout<<h[i]<<" ";
}
int main()
{
cout<<"请输入元素个数:"<<endl;
cin>>n;
for(int i=1;i<=n;i++)
cin>>h[i];
makeHeap();
print();
cout<<endl;
insert(4);
print();
cout<<endl;
del(2);
print();
cout<<endl;
return 0;
}
时间复杂度
所有操作的时间复杂度为O(logn),创建堆的时间复杂度为O(n)
着重分析创建堆

总结
容易在循环判断的地方出错,开始是直接在while(done || 2*i>n)导致没有进入循环,后来是循环条件出错,导致死循环。以后要注意循环!!!

浙公网安备 33010602011771号