使用C++构建一个优先级队列的实现

 更新时间:2025年02月06日 09:04:16   作者:zhoudeng666  
优先级队列是一种特殊的队列数据结构,本文主要介绍了使用C++构建一个优先级队列的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1.优先级队列的介绍

优先级队列是一种特殊的队列数据结构,它是队列,但又不完全是,因为它要将装载的数据进行优先级排序,找到一个最大或者最小优先级的元素,下一次出队列的元素就是这个元素,所以说它不完全是一个队列,优先级队列广泛应用于任务调度、资源分配、事件处理、Dijkstra算法、A*搜索算法等领域。

2.优先级队列的设计

 个人感觉,设计一个优先级队列就是一个堆建立和调整的过程,因为要装载元素,所以我们采用vector来作为成员变量,后续就是对与这个vector变量的管理就行了,因为我们只是简单设计一个优先级队列,所以并没有设计在优先级队列中传入函数进行比较的过程,只是简单的比较大小的过程,首先我们要设计向上调整函数和向下调整函数,因为这个的构造函数和析构函数非常简单,这里我就不过多赘述了。

向上调整函数

向上调整函数就是子节点与父节点做比较,这里我们假设建小堆,如果子节点小于父节点,那么这个堆就是有问题的,所以要进行交换,将子节点与父节点进行交换,但是我们又要考虑交换以后得子节点也就是现在的父节点是否和他现在的父节点又是不对的关系的,所以我们要进行循环,只有当节点为0,也就是根节点或者,子节点小于父节点时,进行循环退出

void siftUp(size_t index)
{
    
    while (index > 0)
    {
        int father = index / 2;
        
        if (list[father] > list[index])
        {
            swap(list[father], list[index]);
            index = father;
        }
        else
        {
            break;
        }
    }
}

向下调整函数

向下调整就是判断你是否比你的两个孩子都要小,逻辑和向上调整函数差不多,只是要和两个孩子都比一次,或者找最小的那个孩子比,主要是要知道孩子是index/2-1和index/2-2就行

void siftDown(size_t index)
{
    while (index <= list.size())
    {
        leftson = index * 2 + 1;
        rightson = index * 2 + 2;
        if (list[index] > list[leftson])
        {
            swap(list[index], list[leftson])
                index = leftson;
        }
        else if (list[index] > list[rightson])
        {
            swap(list[index], list[rightson]);
            index = rightson;
        }
        else
        {
            break;
        }
    }
}

建堆函数

在构造函数的第一步肯定是拷贝构造对应的vector,然后得到的这个vector大概率不是一个堆,因此要对它进行调整,使得它可以成为一个符合规则的堆,一般建堆有两种策略,一种是自下而上的sift down方法,另一种是自上而下的sift up方法。这里我们使用sit down 向下调整的方法,找到最后一个非叶子节点,也就是list.size()/2,然后对每个非叶子节点进行向下调整

explicit Heap(const std::vector<T>& array)
    :list(array)
{
    buildHeap();
}
void buildHeap()
{
    for (int i = list.size() / 2 ; i >=0  ; i--)
    {
        siftDown(i);
   }
}

插入函数

当我们插入一个元素时,我们首先是尾插入vector列表,然后对这个元素进行向上调整,就使得这个堆变得规则

void insert(const T& value)
{
    list.insert(value);
    siftUp(list.size() - 1);
}

获取顶端元素函数

我们建立这个堆或者说维护这个优先级队列肯定是为了得到一个有价值的元素,所有这个堆里面最有价值的元素当然时堆顶元素,但是当我们得到堆顶元素时,这个堆也会被破坏,所以,我们一般会将堆顶元素和最后一个元素进行交换,然后再对堆顶元素进行向下调整,就让堆保持合适的规则

void removeTop()
{
    if (list.empty()) {
        throw std::out_of_range("Heap is empty");
    }
    swap(list[0], list[list.size() - 1]);
    siftDown(0);
    list.erase(list.end() - 1);
}

到此这篇关于使用C++构建一个优先级队列的实现的文章就介绍到这了,更多相关C++ 优先级队列内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++数组放在main函数内外的区别

    C++数组放在main函数内外的区别

    大家好,本篇文章主要讲的是C++数组放在main函数内外的区别,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • 利用C语言将点分十进制的IP字符串转成4个整数

    利用C语言将点分十进制的IP字符串转成4个整数

    这篇文章主要为大家详细介绍了如何利用C语言实现将点分十进制的IP字符串转成4个整数,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-01-01
  • C++实现获取时间戳和计算运行时长

    C++实现获取时间戳和计算运行时长

    这篇文章主要为大家详细介绍了如何使用C++实现获取时间戳和计算运行时长功能,文中的示例代码讲解详细,有需要的小伙伴可以参考一下
    2024-12-12
  • C语言实现简单学生选课管理系统

    C语言实现简单学生选课管理系统

    这篇文章主要为大家详细介绍了C语言实现简单学生选课管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • C++ 函数的介绍

    C++ 函数的介绍

    本篇主要介绍了函数的基础概念以及一些特殊的函数方法和类型,函数重载以及函数指针,下面一起进入文章学习详细的内容吧,需要的朋友也可以参考一下
    2021-12-12
  • C++11语法之右值引用的示例讲解

    C++11语法之右值引用的示例讲解

    右值引用,一般是在深拷贝的类,实现移动构造和移动赋值,能够解决左值引用无法做到的传返回值的效率问题,下面跟随小编一起学习下C++11语法之右值引用的问题
    2022-04-04
  • C++ OpenCV生成蒙太奇图像的示例详解

    C++ OpenCV生成蒙太奇图像的示例详解

    图片的蒙太奇效果,一般称为马赛克图。由很多小图拼接成一个大图。这篇文章主要为大家介绍如何利用C++ OpenCV实现生成蒙太奇图像,感兴趣的可以了解一下
    2022-01-01
  • 使用C++开发一个串口读写软件的实现步骤

    使用C++开发一个串口读写软件的实现步骤

    这篇文章主要介绍了使用xmake(一个项目管理工具兼包管理工具)和asio2(一个asio的框架,可以实现轻松各种网络应用,一般支持tcp,udp,http,websocket,rpc,ssl,icmp,serial_port.)来快速的开发个串口读写软件(整合例程),需要的朋友可以参考下
    2025-04-04
  • C++实现扫雷、排雷小游戏

    C++实现扫雷、排雷小游戏

    这篇文章主要为大家详细介绍了C++实现扫雷、排雷小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • 使用C语言访问51单片机中存储器的核心代码

    使用C语言访问51单片机中存储器的核心代码

    这篇文章主要介绍了使用C语言访问51单片机中存储器的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01

最新评论