堆的定义:
将一系列元素存于数组a中,数组a中的元素必须满足从第一个元素开始a[i]>=a[i * 2]&&a[i]>=a[i * 2+1] || a[i]<=a[i * 2]&&a[i]<=a[i * 2+1]
堆也就是完全二叉树!
建堆:
int cnt=0;
void create(int x)
{
a[++cnt]=x;
int t=cnt;
while(t>1&&a[t/2]>=a[t])//此处建立的是最小堆
{
a[t]=a[t/2];
a[t/2]=x;
t/=2;
}
}
int main()
{
for(i=1;i<=n;i++)
{
scanf("%d",&k);
create(k);//一个元素一个元素的加入
}
}
建立完之后,数组a中第一个元素为总的树根。
然后对于每一个元素a[i]。a[i2]和a[i2+1]是他的儿子,a[i2]和a[i2+1]互为兄弟结点。
若是已经给出你一个堆存储在数组a中,让你求一次堆排序过后的序列
//堆排序,其特点是 前后分为两部分,后面部分有序,前面部分无序
//堆排序的一次过程就是:将前面部分的b[1]放到后面有序的部分,然后再对前面部分进行向下调整满足每个节点的值大于其左右儿子
k=n; //堆存储在数组b中,b[1]~b[n]
while(b[k]>b[1])
k--;
swap(b[1],b[k]);
down(1,k-1); //区间[k,n]已经排好,在区间[1,k-1]中向下调整
//向下调整
void down(int u, int size){ //u表示堆顶的坐标,size表示当前堆的大小
int t=u;
if(u*2<=size && b[t]<b[u*2])
t=2*u;
if(u*2+1<=size && b[t]<b[u*2+1])
t=u*2+1;
if(t!=u) //此结点不是最大的,交换,并且递归
{
swap(b[t],b[u]);
down(t,size);
}
}