实现优先级队列

优先级队列概念

优先级队列是一种按元素优先级大小顺序出队的队列,与普通队列先进先出不同。每一个元素都有优先权,分为元素值越大优先级越高、元素值越小,优先级越高两种;虽然它是一种队列,但是用堆的思想完成的(队列里面堆排序)。


小根堆的两种调整方法

从上到下

还记得堆排序中小根堆交换根和最后一个元素位置后的调整吗,那相当于在根的位置(队头)放入了一个值大的元素,然后从上往下调整,从使上面的大元素移到后面去:

void FilterDown(int* nums, int start,int end)
{
    int i = start, j = 2 * i + 1;
    int tmp = nums[i];
    while (j <= end)
    {
        if (j<end && nums[j]>nums[j + 1])j++;
        if (tmp <= nums[j])break;
        nums[i] = nums[j];
        i = j;
        j = i * 2 + 1;
    }
    nums[i] = tmp;
}

从下往上

这种方法相当于在队尾部放入了一个值小的元素,然后想办法把它移动上去

void FilterUP(int* nums, int start)
{
    int j = start, i = (j - 1) / 2;
    int tmp = nums[j];
    while (j > 0)
    {
        if (tmp >= nums[i])break;
        nums[j] = nums[i];//大的数往下层移
        j = i;
        i = (j - 1) / 2;
    }
    nums[j] = tmp;
}

这两个方法在实现优先级队列中需要用到,是关键代码。


构造一个优先级队列类

私有部分:队列里面包含三个变量分别指向元素,保存队尾下标,元素个数

    int* data;//元素
    int cursize;//当前元素个数
    int maxsize;//队尾下标

公共部分:

成员构造、析构函数,因为有指针,所以必须写;上面说到的两个调整函数;数据出队入队;判断队列空或满;取队列内元素个数;清除队列;

    MinHeap(int sz = 100);
    ~MinHeap();
    //向下调整
    static void FilterDown(int* nums, int start, int end);
    //向上调整
    static void FilterUP(int* nums, int start);
    int getSize()const { return cursize; }
    bool isEmpty() const { return getSize() == 0; }
    bool isFull()const { return getSize() == maxsize; }
    void clear() { cursize = 0; }
//入队
    bool push(const int& val);
//出队
    bool remove(int& val);

入队时,先判断队列是否满,如果可以入队,调整cursize和maxsize的大小,将元素放入队尾,之后使用向上调整函数完成优先级队列内部顺序的调整。

出队时,先判断队列是否为空,如果可以出队,则将队头元素出,队头即为优先级最大的元素,然后将队尾元素放到队头,,调整cursize和maxsize的大小,使用向下调整函数调整顺序。


完整代码

class MinHeap
{
private:
    int* data;//元素
    int cursize;//当前元素个数
    int maxsize;//队尾下标
public:
    MinHeap(int sz = 100)
    {
        cursize = 0;
        maxsize = sz;
        data = new int[maxsize];
    }
    ~MinHeap()
    {
        delete[]data;
        data = NULL;
        cursize = 0;
        maxsize = 0;
    }
    //向下调整
    static void FilterDown(int* nums, int start, int end)
    {
        int i = start, j = 2 * i + 1;
        int tmp = nums[i];
        while (j <= end)
        {
            if (j<end && nums[j]>nums[j + 1])j++;
            if (tmp <= nums[j])break;
            nums[i] = nums[j];
            i = j;
            j = i * 2 + 1;
        }
        nums[i] = tmp;
    }
    //向上调整
    static void FilterUP(int* nums, int start)
    {
        int j = start, i = (j - 1) / 2;
        int tmp = nums[j];
        while (j > 0)
        {
            if (tmp >= nums[i])break;
            nums[j] = nums[i];//大的数往下层移
            j = i;
            i = (j - 1) / 2;
        }
        nums[j] = tmp;
    }
    int getSize()const { return cursize; }
    bool isEmpty() const { return getSize() == 0; }
    bool isFull()const { return getSize() == maxsize; }
    void clear() { cursize = 0; }
//入队
    bool push(const int& val)
    {
        if (isFull())return false;
        data[cursize++] = val;
        FilterUP(data, cursize - 1);//从后往前调
        return true;
    }
//出队
    bool remove(int& val)
    {
        if (isEmpty())return false;
        val = data[0];
        data[0] = data[cursize - 1];//把最后一个元素放第一个,覆盖取出的
        cursize--;
        FilterDown(data, 0, cursize - 1);
        return true;
    }
};

使用测试

int main()
{
    MinHeap mh(100);
    mh.push(12);
    mh.push(23);
    mh.push(100);
    mh.push(89);
    mh.push(45);
    while (!mh.isEmpty())
    {
        int x = 0;
        mh.remove(x);
        printf("%-5d\n", x);
    }
    mh.clear();
    mh.clear();
}

如果需要改成值越大优先级越大,只需修改调整函数中if里面的大于小于号:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要基于RabbitMQ实现优先级队列,需要使用插件rabbitmq_priority_queue,该插件提供了消息优先级队列的支持。以下是添加队列的步骤: 1. 确保RabbitMQ服务器上已经安装了rabbitmq_priority_queue插件。如果没有安装,需要执行以下命令安装: ``` rabbitmq-plugins enable rabbitmq_priority_queue ``` 2. 使用AMQP客户端连接到RabbitMQ服务器,并创建队列时,通过设置x-max-priority参数来指定最大优先级数。例如,以下是使用Python pika库创建一个具有10个优先级级别的队列的示例代码: ```python import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() args = {"x-max-priority": 10} channel.queue_declare(queue='my_queue', arguments=args) connection.close() ``` 在上面的示例中,我们将队列命名为my_queue,并通过args参数将x-max-priority设置为10。 3. 发布消息时,需要在消息属性中设置priority属性,指定该消息的优先级。例如,以下是使用Python pika库发布消息并指定优先级的示例代码: ```python import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() properties = pika.BasicProperties(priority=5) channel.basic_publish(exchange='', routing_key='my_queue', body='Hello, World!', properties=properties) connection.close() ``` 在上面的示例中,我们通过properties参数将priority属性设置为5,指定该消息的优先级为5。 通过上述步骤,我们就可以基于RabbitMQ实现优先级队列了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曦樂~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值