优先级队列(大顶堆实现)

使用大顶堆可以高效的实现优先级队列,具体大顶堆的用法,可参考:堆排序

优先级队列是用来维护一组元素构成的集合S 的数据结构,每一个元素都含有一个关键字key。一个最大优先级队列支持一下操作:

Insert(S,x):把元素x插入到队列中,与一般队列不同的是,优先级队列入队的操作总和队列中已有的元素进行比较,找到适当的位置进行插入,本例中,入队的操作总是能使优先级队列保持有序状态。

Maximum(S):返回S中具有最大关键字的元素

Extract_Max(S):去掉并返回S中具有最大关键字的元素,其实就是出队操作,在大顶堆中,由于最大元素总是在根节点处,所以出队时仅需要去掉根节点并重新建堆即可。

Increase_Key(S,x,k):将元素x的值增加到k,这里k的值不能小于x的值

以下是具体实现代码:

#include <stdio.h>
#include <stdlib.h>

#define INF -10000//为什么要设置为那么小?相当于把这个元素放在队尾,增加到key时一层一层向上,完成队列的入队操作
#define MAX 20

/*一下操作是大顶堆的基本操作*/

//堆的大小,注意,和数组本身的大小事有区别的,在堆排序的函数中要尤其小心
int Heap_Size=20;

//保持堆的性质,其实就是拿A[i]和左右两个孩子比较大小,然后递归下去就行了
void MAX_HEAPIFY(int* A,int i)
{
    int Largest;
    int L=2*i;
    int R=2*i+1;
    if(L<=Heap_Size&&A[L]>A[i])
        Largest=L;
    else
        Largest=i;
    if(R<=Heap_Size&&A[R]>A[Largest])
        Largest=R;
    if(Largest!=i)
    {
        int temp=A[i];
        A[i]=A[Largest];
        A[Largest]=temp;
        MAX_HEAPIFY(A,Largest);
    }
}

//建堆的过程
void Build_Max_Heap(int* A)
{
    int i=MAX/2;
    for(;i>=1;i--)
    {
        MAX_HEAPIFY(A,i);
    }
}

//堆排序算法的过程
void Heap_Sort(int* A)
{
    Build_Max_Heap(A);
    int i=MAX;
    for(;i>2;i--)
    {
        printf("%d ",A[1]);
        int temp=A[1];
        A[1]=A[i];
        A[i]=temp;
        Heap_Size--;
        MAX_HEAPIFY(A,1);
    }
}

/*以下代码是优先级队列的基本操作*/

//返回最大值
int Heap_Maximum(int* A)
{
    return A[1];
}

//出队操作,也就是讲A[1]出队,并重新生成大顶堆
int Heap_Extract_Max(int* A)
{
    if(Heap_Size<1)
        exit(-1);
    int max=A[1];
    A[1]=A[Heap_Size];
    Heap_Size--;
    MAX_HEAPIFY(A,1);
    return max;
}

//将其中一个元素的值增大到key后堆的变化,主要为后续的入队操作打下基础
void Heap_Incerase_Key(int* A,int i,int key)
{
    if(key<A[i])
        exit(-1);
    A[i]=key;
    while(i>1&&A[i/2]<A[i])
    {
        int temp=A[i/2];
        A[i/2]=A[i];
        A[i]=temp;
        i=i/2;
    }
}

//入队操作,在数组左后一个位置放上值为非常小的数,然后通过Heap_Incerase_Key重新构造堆的结构
void Max_Heap_Insert(int* A,int key)
{
    Heap_Size++;
    A[Heap_Size]=INF;
    Heap_Incerase_Key(A,Heap_Size,key);
}

//主函数进行测试,注意,数组下标从1开始,第一个元素存放数组的大小
int main(void)
{
    int A[MAX+1]={MAX,34,23,67,34,2,5,6,1,78,34,2,4,5,44,12,6,97,23,54,10};
    Build_Max_Heap(A);
    printf("出队的元素是%d\n",Heap_Extract_Max(A));
    printf("出队的元素是%d\n",Heap_Extract_Max(A));
    Max_Heap_Insert(A,100);
    printf("出队的元素是%d\n",Heap_Extract_Max(A));
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值