“堆”这个词最初是在堆排序中提出的,但后来就逐渐指“肥料收集存储区”,就像程序设计语言Lisp和Java中所提供的设施一样。此处堆都是指一种数据结构。
堆亦被称为:优先队列。堆通常是一个可以被看做一颗树的数组对象。这里先联系堆排序
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int init(int x[])
{
int i = 0;
while(scanf("%d",&x[i++]) != EOF);
return i - 1;
}
//保持堆的性质,假设以left(i)和right(i) 为根的两颗树都是最大堆
void maxHeapify(int x[],int xSize,int i)
{
int largest = 0;
int left = ((i + 1) << 1) - 1;
int right = (i + 1) << 1;
if(left < xSize && x[left] > x[i])
largest = left;
else
largest = i;
if(right < xSize && x[right] > x[largest])
largest = right;
if(largest != i)
{
swap(x[i],x[largest]);
maxHeapify(x,xSize,largest);
}
}
//自底向上用maxHeapify()将x[]编程最大堆
void buildMaxHeap(int x[],int xSize)
{
for(int i = (xSize - 1) / 2; i >= 0; i--)
maxHeapify(x,xSize,i);
}
void heapSort(int x[],int xSize)
{
buildMaxHeap(x,xSize);
for(int i = xSize - 1; i > 0; i--)
{
swap(x[i],x[0]);
maxHeapify(x,i,0);
}
}
int main()
{
/****************************/
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
/****************************/
int x[50];
int xSize;
xSize = init(x);
heapSort(x,xSize);
for(int i = 0; i < xSize; i++)
printf("%d ",x[i]);
/****************************/
#ifndef ONLIINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
/****************************/
return 0;
}
测试通过~
使用堆实现优先级队列。诸如作业调度或事件驱动的模拟应用中,优先级队列的元素对应着应用中的对象。通常我们需要确定一个给定的队列中元素所对应的应用对象,反之亦然。当用堆来实现优先级队列时,需要在堆中的每个元素里存储对应的应用对象的 柄(handle)。对象柄的准确表示到底怎么样(如,一个指针,一个整型数等等)还取决于具体的应用。同样的,我们需要将堆中元素的柄存储到其对应的应用对象中。
下面是最大堆实现优先级队列,模拟作业调度。作业有一个优先级proority和类似一个控制块blockThing,暂时用它表示作业号。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
//堆实现最大优先队列,模拟作业调度
//作业结构:优先级int priority,控制块int block 表示
typedef struct node
{
int priority;
int blockThing;
}queueJob;
void maxHeapify(queueJob A[],int aSize,int i)
{
int largest = 0;
int left = ((i + 1) << 1) - 1;
int right = (i + 1) << 1;
if(left < aSize && A[left].priority > A[i].priority)
largest = left;
else
largest = i;
if(right < aSize && A[right].priority > A[largest].priority)
largest = right;
if(largest != i)
{
swap(A[i],A[largest]);
maxHeapify(A,aSize,largest);
}
}
void buildMaxHeap(queueJob A[],int aSize)
{
for(int i = (aSize - 1) / 2; i >= 0; i--)
maxHeapify(A,aSize,i);
}
/********************************优先队列函数******************/
queueJob maximumHeap(queueJob A[])
{
return A[0];
}
queueJob extractMaxHeap(queueJob A[],int& aSize)
{
if(aSize < 0)
{
printf("heap underflow\n");
exit(1);
}
queueJob max = A[0];
A[0] = A[aSize - 1];
aSize -= 1;
maxHeapify(A,aSize,0);
return max;
}
void increaseKeyHeap(queueJob A[],int aSize,int id, int k)//将第i个作业的优先级增加到k
{
int i = -1;
for(int j = 0; j < aSize; j++)
{
if(A[j].blockThing == id)
{
i = j;
break;
}
}
if(i == -1){printf("错误\n");exit(1);}
if(k < A[i].priority)
{
printf("新的优先级必须高于现有的");
exit(1);
}
A[i].priority = k;
while(i > 0 && A[(i-1) / 2].priority < A[i].priority)
{
swap(A[i],A[(i-1) / 2]);
i = (i - 1) / 2;
}
}
int insertMaxHeap(queueJob A[],int aSize,queueJob key)
{
aSize = aSize + 1;
A[aSize - 1].priority = 0xffffffff;
A[aSize - 1].blockThing = key.blockThing;
increaseKeyHeap(A,aSize,key.blockThing,key.priority);
return aSize;
}
int main()
{
/****************************/
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
/****************************/
int jobNum = 0;
scanf("%d",&jobNum);
queueJob* job = (queueJob*)malloc(2 * jobNum * sizeof(queueJob));
for(int i = 0; i < jobNum; i++)
{
scanf("%d %d",&job[i].priority,&job[i].blockThing);
}
buildMaxHeap(job,jobNum);//建立最大堆
queueJob top = maximumHeap(job);
printf("优先级作业最大是:%d %d",top.priority,top.blockThing);
increaseKeyHeap(job,jobNum,101,20);
top = maximumHeap(job);
printf("优先级作业最大是:%d %d",top.priority,top.blockThing);
queueJob x;
x.priority = 10;
x.blockThing = 122;
jobNum = insertMaxHeap(job,jobNum,x);
printf("\n%d排序后:\n",jobNum);
int num = jobNum;
for(int i = 0; i < num; i++)
{
top = extractMaxHeap(job,jobNum);
printf("%d %d\n",top.priority,top.blockThing);
}
/****************************/
#ifndef ONLIINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
/****************************/
return 0;
}