浅谈C++|STL之stack+queue+priority_queue篇

news2025/1/12 10:11:59

在这里插入图片描述

一.stack基本概念

栈(Stack)是一种常见的线性数据结构,遵循后进先出(Last-In-First-Out,LIFO)的原则。类似于我们在现实生活中堆叠书本或盘子的方式,最后放入的元素最先被取出。

在栈中,元素的插入操作(入栈)是在栈顶进行,而元素的删除操作(出栈)也是在栈顶进行。这使得栈成为一种适合于后续操作依赖于最近插入的元素的数据结构。栈通常具有以下两个基本操作:

  1. 入栈(Push):将元素添加到栈顶。
  2. 出栈(Pop):从栈顶移除一个元素。

除了基本的入栈和出栈操作,栈还具有以下重要概念:

  • 栈顶(Top):指向栈中最新插入的元素的指针或引用。这是我们可以进行出栈和入栈操作的位置。
  • 栈底(Bottom):指向栈中最先插入的元素的指针或引用。
  • 空栈(Empty Stack):不包含任何元素的栈。
  • 满栈(Full Stack):当栈达到其最大容量时,无法再插入新的元素。

栈可以使用数组或链表等数据结构来实现。在 C++ 标准库中,我们可以使用 std::stack 模板类来实现栈,它默认使用 std::deque 作为底层容器。

需要注意的是,栈是一种单向的数据结构,只能从栈顶插入和删除元素。如果需要在栈中间位置进行操作,可能需要转换为其他数据结构或使用额外的辅助数据结构。

栈在算法、语法分析、递归调用等各种场景中都有广泛的应用。它有助于实现各种基于后进先出顺序的问题和任务。

在这里插入图片描述

栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为

二.stack函数接口

当使用栈(std::stack)时,以下是一些重要的详细信息和注意事项:

  • 包含头文件:要使用 std::stack,需要包含 <stack> 头文件。

  • 栈的创建:可以通过下面的方式声明一个栈。

    std::stack<int> st;
    

    在上述示例中,int 是栈中元素的类型,可以根据需要替换为其他类型。

  • 元素插入:可以使用 push 方法将元素压入栈顶。

    st.push(42);
    

    上述示例将整数 42 压入了栈顶。

  • 元素访问:可以使用 top 方法访问栈顶元素的值。

    std::cout << st.top(); // 输出栈顶元素的值(不删除)
    

    注意,top 方法不会从栈中删除栈顶元素,只是返回栈顶元素的值。

  • 元素删除:可以使用 pop 方法从栈中删除栈顶元素。

    st.pop();
    

    上述示例将栈顶元素从栈中删除。

  • 栈的大小:可以使用 size 方法获取栈内元素的数量。

    std::cout << st.size(); // 输出栈中元素的个数
    
  • 栈的判空:可以使用 empty 方法判断栈是否为空。

    if (st.empty()) {
        // 栈为空
    } else {
        // 栈不为空
    }
    

    empty 方法在栈为空时返回 true,否则返回 false

整理成表格:

构造函数和析构函数描述
stack()默认构造函数,创建一个空的栈
stack(const stack& other)复制构造函数,创建一个新的栈并复制另一个栈的内容
~stack()析构函数,销毁栈
运算符重载描述
operator=赋值运算符,将一个栈的内容赋值给另一个栈
operator==比较运算符,判断两个栈是否相等
operator!=比较运算符,判断两个栈是否不相等
成员函数描述
push(value_type& value)将元素压入栈顶
pop()弹出栈顶元素
top()返回栈顶元素的引用(不删除)
size()返回栈中元素的数量
empty()判断栈是否为空
swap(stack& other)交换两个栈的内容

在上述表格中,value_type 是栈中元素的类型。请注意,栈类 std::stack 是基于其他容器实现的,默认情况下使用 std::deque 作为底层容器。可以使用其他容器,如 std::vectorstd::list,作为底层容器来实现栈。

三.queue基本概念

队列(Queue)是一种常见的线性数据结构,遵循先进先出(First-In-First-Out,FIFO)的原则。它类似于我们在现实生活中排队等待的场景,先来的人先被服务。

在队列中,元素的插入操作(入队)是在队列的尾部进行,而元素的删除操作(出队)是在队列的头部进行。这使得队列成为一种适合于等待行列或任务调度的数据结构。队列通常有以下两个基本操作:

  1. 入队(Enqueue):将元素添加到队列的末尾(尾部)。
  2. 出队(Dequeue):从队列的头部移除一个元素。

除了基本的入队和出队操作,队列还具有以下重要概念:

  • 队列头部(Front):指向队列中第一个元素的指针或引用。这是我们可以出队的位置。
  • 队列尾部(Back):指向队列中最后一个元素的指针或引用。这是我们可以入队的位置。
  • 空队列(Empty Queue):不包含任何元素的队列。
  • 满队列(Full Queue):当队列达到其最大容量时,无法再入队新的元素。

队列可以使用线性数组、链表或其他数据结构来实现。在C++标准库中,我们可以使用 std::queue 模板类来实现队列,它默认使用 std::deque 作为底层容器。

需要注意的是,队列是一种单向的数据结构,只能从队列的头部删除元素,从队列的尾部插入元素。如果需要在队列中间位置进行操作,可能需要转换为其他数据结构或使用额外的辅助数据结构。

队列在算法、操作系统、网络通信等领域中都有广泛的应用。它有助于实现各种基于顺序处理的问题和任务调度。

在这里插入图片描述

四.queue函数接口

构造函数和析构函数:

  • queue():默认构造函数,创建一个空的队列。
  • queue(const queue& other):复制构造函数,创建一个新的队列并复制另一个队列的内容。
  • ~queue():析构函数,销毁队列。

运算符重载:

  • operator=:赋值运算符,将一个队列的内容赋值给另一个队列。
  • operator==:比较运算符,判断两个队列是否相等。
  • operator!=:比较运算符,判断两个队列是否不相等。

成员函数:

  • push(value_type& value):将元素 value 插入队列的尾部。
  • pop():从队列的头部移除一个元素。
  • front():返回队列头部的元素。
  • back():返回队列尾部的元素。
  • empty():判断队列是否为空,如果为空则返回 true,不为空则返回 false
  • size():返回队列中元素的个数。
  • swap(queue& other):交换两个队列的内容。

请注意,value_type 是队列中元素的类型。默认情况下,std::queue 是使用 std::deque 作为底层容器来实现的,但也可以使用其他容器,如 std::liststd::vector。如果需要在队列中访问或修改中间元素,则需要采用其他方式,比如遍历队列实现相关操作。

整理成表格:

构造函数和析构函数描述
queue()默认构造函数,创建一个空的队列
queue(const queue& other)复制构造函数,创建一个新的队列并复制另一个队列的内容
~queue()析构函数,销毁队列
运算符重载描述
operator=赋值运算符,将一个队列的内容赋值给另一个队列
operator==比较运算符,判断两个队列是否相等
operator!=比较运算符,判断两个队列是否不相等
成员函数描述
push(value_type& value)将元素 value 插入队列的尾部
pop()移除队列头部的元素
front()返回队列头部的元素
back()返回队列尾部的元素
empty()判断队列是否为空
size()返回队列中元素的数量
swap(queue& other)交换两个队列的内容

五.priority_queue基本概念

std::priority_queue 是 C++ 标准库中的一个模板类,用于实现优先队列(Priority Queue)。优先队列是一种特殊的队列数据结构,它根据元素的优先级自动进行排序,优先级高的元素排在前面。默认情况下,std::priority_queue 使用最大堆(max heap)来实现。

以下是 std::priority_queue 的基本概念:

  • 元素的优先级由比较函数(Comparator)确定。对于基本数据类型(如整数、浮点数),可以使用默认的比较函数(std::less)来进行比较。对于自定义类型,需要提供比较函数或比较函数对象。
  • 元素在被插入到优先队列时会自动根据优先级进行排序,优先级高的元素会放在前面。当需要从队列中取出元素时,优先队列会返回当前优先级最高的元素,并将其移出队列。

std::priority_queue 支持以下常用的操作:

  • std::priority_queue<T>:创建一个空的优先队列,元素类型为 T
  • std::priority_queue<T, Container>:创建一个空的优先队列,元素类型为 T,使用容器 Container 来存储元素。
  • push(element):将元素 element 插入到优先队列中,根据元素的优先级进行排序。
  • pop():移除队列中优先级最高的元素(堆顶元素)。
  • top():获取当前队列中优先级最高的元素(堆顶元素)。
  • empty():检查优先队列是否为空,返回布尔值。
  • size():返回优先队列中元素的个数。
  • swap(other_queue):交换两个优先队列的内容。

需要注意的是,默认情况下,std::priority_queue 是最大堆,即优先级高的元素位于堆的顶部。如果需要最小堆,可以通过提供自定义的比较函数或比较函数对象来实现。

上述操作和概念使得 std::priority_queue 成为在需要根据优先级对元素进行排序和处理的场景中非常有用的工具。

六.priority_queue建立

要使用 std::priority_queue,你需要包含头文件 queue,该头文件中已经定义了优先队列模板类。

以下是使用 std::priority_queue 构建优先队列的详细步骤:

  1. 包含头文件:
#include <queue>
  1. 定义元素类型和比较函数(可选):

如果元素类型是基本数据类型(如整数、浮点数),则可以直接使用默认的比较函数 std::less 进行比较。如果元素类型是自定义类型,你需要提供一个能够比较元素优先级的比较函数或比较函数对象。

bool compareFunction(const T& a, const T& b) {
    // 自定义比较规则,返回 true 表示 a 的优先级高于 b
    // 或者使用逆序,返回 true 表示 a 的优先级低于 b
    // 比较函数应该根据元素类型的实际情况进行定义
}
  1. 声明优先队列对象:
std::priority_queue<T, Container, Compare> pq;
  • T:元素类型。
  • Container:可选参数,指定容器类型,默认为 std::vector<T>
  • Compare:可选参数,指定比较函数或比较函数对象,默认为 std::less<T>

示例:

std::priority_queue<int> pq; // 创建一个存储 int 类型的优先队列,默认使用 std::vector 作为底层容器,使用 std::less 进行比较

std::priority_queue<double, std::vector<double>, std::greater<double>> pq; // 创建一个存储 double 类型的优先队列,使用 std::vector 作为底层容器,使用 std::greater 进行比较

bool compareFunction(const CustomType& a, const CustomType& b) {
    // 自定义比较函数的实现
}

std::priority_queue<CustomType, std::vector<CustomType>, decltype(compareFunction)*> pq(compareFunction); // 创建一个存储自定义类型 CustomType 的优先队列,使用 std::vector 作为底层容器,使用自定义的 compareFunction 进行比较
  1. 插入元素:

使用 push 方法将元素插入到优先队列中,并根据元素的优先级进行排序。

pq.push(element);

示例:

pq.push(3);
pq.push(1);
pq.push(4);
  1. 删除元素:

使用 pop 方法移除优先队列中优先级最高的元素(堆顶元素)。

pq.pop();
  1. 访问顶部元素:

使用 top 方法获取当前优先队列中优先级最高的元素(堆顶元素)。

T topElement = pq.top();
  1. 检查优先队列是否为空:

使用 empty 方法判断优先队列是否为空。

if (pq.empty()) {
    // 优先队列为空
}
  1. 获取优先队列的大小:

使用 size 方法获取当前优先队列中的元素个数。

int size = pq.size();
  1. 交换优先队列的内容:

使用 swap 方法交换两个优先队列的内容。

std::priority_queue<T, Container, Compare> otherPQ;
pq.swap(otherPQ);

整理成表格:

函数描述
push(element)插入元素 element 到优先队列中,根据元素的优先级进行排序。
pop()移除优先队列中优先级最高的元素(堆顶元素)。
top()返回当前优先队列中优先级最高的元素(堆顶元素)。在不进行删除操作的情况下,访问优先队列中的元素。
empty()检查优先队列是否为空,如果队列中没有元素则返回 true,否则返回 false
size()返回优先队列中的元素个数。
swap(other_queue)交换两个优先队列的内容。
emplace(args...)在优先队列中原地构造一个元素,使用给定的参数 args
container()返回一个包含优先队列所有元素的容器的副本。此函数在 C++11 中引入。
get_container()返回一个指向底层容器的指针。只有 Container 参数不为空的情况下才可用。此函数在 C++17 中引入。
size_type表示 std::priority_queue 中的大小类型。在 C++17 中引入。
value_compare表示 std::priority_queue 中的比较对象。在 C++17 中引入。
value_type表示 std::priority_queue 中的元素类型。
reference表示 std::priority_queue 中的引用类型,用于获取、修改队列中元素的引用。
const_reference表示 std::priority_queue 中的常量引用类型,用于获取队列中元素的常量引用。
iterator, const_iterator表示 std::priority_queue 的迭代器类型,用于遍历优先队列中的元素。
reverse_iterator, const_reverse_iterator表示 std::priority_queue 的逆向迭代器类型,用于逆序遍历优先队列中的元素。

构造函数(了解即可)

下面是 std::priority_queue 的构造函数及相关参数的表格:

构造函数描述
explicit priority_queue(const Compare& compare = Compare(), const Container& container = Container())创建一个空的优先队列,元素类型为 T,使用给定的比较函数和容器来进行构造。
explicit priority_queue(const Compare& compare, Container&& container)创建一个空的优先队列,元素类型为 T,使用给定的比较函数和右值引用类型的容器来进行构造。
template <class InputIterator> priority_queue(InputIterator first, InputIterator last, const Compare& compare = Compare(), const Container& container = Container())创建一个优先队列,使用指定范围 [first, last) 中的元素,以及给定的比较函数和容器来进行构造。
template <class InputIterator> priority_queue(InputIterator first, InputIterator last, const Compare& compare, Container&& container)创建一个优先队列,使用指定范围 [first, last) 中的元素,以及给定的比较函数和右值引用类型的容器来进行构造。
priority_queue(const priority_queue& other)创建一个优先队列,使用另一个优先队列 other 的副本来进行构造。
priority_queue(const priority_queue& other, const Container& container)创建一个优先队列,使用另一个优先队列 other 的副本和给定的容器来进行构造。
priority_queue(priority_queue&& other)创建一个优先队列,使用另一个优先队列 other 的右值引用类型副本来进行构造。
priority_queue(priority_queue&& other, const Container& container)创建一个优先队列,使用另一个优先队列 other 的右值引用类型副本和给定的容器来进行构造。
template <class Alloc> explicit priority_queue(const Compare& compare, const Alloc& alloc)创建一个空的优先队列,元素类型为 T,使用给定的比较函数和分配器 alloc 来进行构造。
template <class Alloc> priority_queue(const Compare& compare, const Container& container, const Alloc& alloc)创建一个空的优先队列,元素类型为 T,使用给定的比较函数、容器和分配器 alloc 来进行构造。
template <class Alloc> priority_queue(const Compare& compare, Container&& container, const Alloc& alloc)创建一个空的优先队列,元素类型为 T,使用给定的比较函数、右值引用类型的容器和分配器 alloc 来进行构造。
`template explicit priority_queue(const Alloc& alloc)创建一个空的优先队列,元素类型为 T,使用默认的比较函数和分配器 alloc 来进行构造。
template <class Alloc> priority_queue(const Container& container, const Alloc& alloc)创建一个优先队列,使用给定的容器和分配器 alloc 进行构造。
template <class Alloc> priority_queue(Container&& container, const Alloc& alloc)创建一个优先队列,使用给定的右值引用类型的容器和分配器 alloc 进行构造。
explicit priority_queue(const Compare& compare, const Container& container, const Alloc& alloc)创建一个空的优先队列,使用给定的比较函数、容器和分配器 alloc 来进行构造。
explicit priority_queue(const Compare& compare, Container&& container, const Alloc& alloc)创建一个空的优先队列,使用给定的比较函数、右值引用类型的容器和分配器 alloc 来进行构造。
priority_queue(const Compare& compare, const Container& container, const Alloc& alloc)创建一个优先队列,使用给定的比较函数、容器和分配器 alloc 进行构造。
priority_queue(const Compare& compare, Container&& container, const Alloc& alloc)创建一个优先队列,使用给定的比较函数、右值引用类型的容器和分配器 alloc 进行构造。

注意:上述表格中的 Compare 是比较函数或比较函数对象类型,Container 是用于存储元素的容器类型,Alloc 是分配器类型。如果未提供相应的参数,默认使用 std::less 进行比较,使用 std::vector 作为容器,使用 std::allocator 进行分配。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1017034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【基于多输出方向的同步异步日志系统】

本项目涉及的到所有源码见以下链接&#xff1a; https://gitee.com/ace-zhe/wz_log 一、项目简介 1.日志的概念&#xff08;白话版&#xff09; 日志类似于日记&#xff0c;通常是指对完成某件事情的过程中状态等的记录&#xff0c;而计算机中的日志是指日志数据&#xff0c…

Python实现的mqtt客户端工具分享,小巧且超轻量级(python+tkinter+paho.mqtt)

mqtt协议调试时需要个客户端工具&#xff0c;但网上找的体积包都很大&#xff0c;都不够小巧和便携。于是趁周末时间用python搞出来了个客户端工具&#xff0c;使用pythontinkerpaho.mqtt实现。源码量很少但功能不弱&#xff0c;相当的轻量级。分享给有需要的小伙伴&#xff0c…

论文写作指导手册

TIPS&#xff1a;最近我们上线了“AI写作大师”&#xff0c;后续会继续围绕论文、文章、文案写相关的文章&#xff0c;来验证写作大师能力如何&#xff0c;敬请持续关注&#xff08; openrabbit.net&#xff09;&#xff5e; 一、论文选题 选题是论文研究的第一步&a…

Prometheus+Grafana可视化监控【Nginx状态】

文章目录 一、安装Docker二、安装Nginx(Docker容器方式)三、安装Prometheus四、安装Grafana五、Pronetheus和Grafana相关联六、安装nginx_exporter七、Grafana添加Nginx监控模板 一、安装Docker 注意&#xff1a;我这里使用之前写好脚本进行安装Docker&#xff0c;如果已经有D…

软件测试中常见的难题

1、需求定义&#xff1a; 需求可能不完整或者不准确&#xff0c;这会导致测试人员无法测试应用程序的所有功能。 例如&#xff1a;在一个电子商务网站上&#xff0c;可能需要测试的某些操作并未在需求中列出&#xff0c;导致测试人员无法测试到这些操作。 对策&#xff1a;测…

MySQL实现单个字段根据特定字符拆分

1.字段内容 2.想得到的效果 步骤1中&#xff0c;每一条记录的FJ字段&#xff0c;根据分号&#xff0c;拆分成多条&#xff0c;如下图所示&#xff1a; 3.具体实现 说明&#xff1a; SELECT DISTINCTsubstring_index(substring_index(a.要拆分的字段, 分隔字符, b.help_top…

自动化项目实战:用requests库自动保存王者荣耀英雄皮肤到本地,文末附源码下载!

前言 王者荣耀是一款备受欢迎的手机游戏&#xff0c;拥有众多精美的英雄皮肤。如果你想获取这些皮肤的图片或者其他相关信息&#xff0c;可以利用Python编写一个简单的爬虫来实现。 安装第三方库 首先&#xff0c;我们需要安装Python的requests和BeautifulSoup库。可以使用…

系列六、Nginx配置实例之反向代理2

一、目标 浏览器网页中访问http://${Linux服务器的IP}:9001/basketball/index.html&#xff0c;浏览器中打印"篮球8080!!!"&#xff1b; 浏览器网页中访问http://${Linux服务器的IP}:9001/football/index.html&#xff0c;浏览器中打印"足球8081!!!"&#…

[NLP] LLM---<训练中文LLama2(五)>对SFT后的LLama2进行DPO训练

当前关于LLM的共识 大型语言模型&#xff08;LLM&#xff09;使 NLP 中微调模型的过程变得更加复杂。最初&#xff0c;当 ChatGPT 等模型首次出现时&#xff0c;最主要的方法是先训练奖励模型&#xff0c;然后优化 LLM 策略。从人类反馈中强化学习&#xff08;RLHF&#xff09…

[字符串和内存函数]错误信息报告函数strerror详解

strerror介绍 strerror是一个C库函数&#xff0c;用于将错误代码转换为对的错误信息字符串。它接受一个整数参数errno&#xff0c;返回一个指向错误信息字符串的指针。 errno是一个全局变量&#xff0c;可以直接使用。它在C语言中用于表示发生错误时的错误码。它是一个整数&…

笔记1.4 计算机网络性能

1. 速率 速率即数据率&#xff08;data rate&#xff09;或称数据传输速率或比特率 单位时间&#xff08;秒&#xff09;传输信息&#xff08;比特&#xff09;量 计算机网络中最重要的一个性能指标 单位&#xff1a;bps、kbps、Mbps k 10^3、M 10^6、G 10^9 速率往往…

autosar 诊断入门

AUTOSAR (汽车开放系统架构) 是一个国际汽车行业的开放和标准化的软件架构。它的主要目标是为了创建一种独立于硬件的软件架构&#xff0c;以提高汽车电子系统的模块化和可重用性。 AUTOSAR架构主要分为两个部分&#xff1a;AUTOSAR Runtime Environment (RTE) 和 AUTOSAR Soft…

HTTP各版本差异

HTTP1.0 无法复用连接 HTTP1.0为每个请求单独新开一个TCP连接 #mermaid-svg-9N3exXRS4VvT4bWF {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-9N3exXRS4VvT4bWF .error-icon{fill:#552222;}#mermaid-svg-9N3exXRS…

集成电路运算放大器[23-9-16]

目录 1、结构组成&#xff1a;差分放大电路、电压放大电路、功率放大电路。 2、同相放大器&#xff1a; 3、反相放大器&#xff1a;一个正电压放大并变为负电压。 4、差分放大电路&#xff1a;输入两个不同的电压&#xff0c;两者的差值乘以放大系数得到输 出电压。 1、结构组…

2.策略模式

UML图 代码 main.cpp #include "Strategy.h" #include "Context.h"void test() {Context* pContext nullptr;/* StrategyA */pContext new Context(new StrategyA());pContext->contextInterface();/* StrategyB */pContext new Context(new Strat…

MybatisPlus(5)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 上篇讲了增删的操作&#xff0c;这篇讲修改操作中的一个问题以及它对应的…

002-第一代硬件系统架构确立及产品选型

第一代硬件系统架构确立及产品选型 文章目录 第一代硬件系统架构确立及产品选型项目介绍摘要硬件架构硬件结构选型及设计单片机选型上位机选型扯点别的 关键字&#xff1a; Qt、 Qml、 信号采集机、 数据处理、 上位机 项目介绍 欢迎来到我们的 QML & C 项目&#xff…

Centos8下载安装JDK8

安装JDK8 一、下载 官网&#xff1a;https://www.oracle.com/java/technologies/downloads/#java8-linux 二、存放到opt目录下 三、解压 tar -zxvf jdk-8u361-linux-x64.tar.gz -C /usr/local如果下载的是tar格式&#xff0c;则安装如下命令解压 tar -zvf jdk-8u361-linu…

Flash的学习

Flash的学习 1 概述 2 特性 STM32 的内部FLASH 包含主存储器、系统存储器以及选项字节区域。 2.1 主存储器 主存储器分为256 页&#xff0c;每页大小为2KB&#xff0c;共512KB。这个分页的概念&#xff0c;实质就是FLASH 存储器 的扇区&#xff0c;与其它FLASH 一样&…

【C++】动态内存管理(79分钟写的文章哪里看不懂了,快来学)

动态内存管理目录&#xff1a; 一、C/C内存分布 在学习了C/C内存区域的划分后&#xff0c;我们来做几道题巩固一下&#xff1a; 1. 选择题&#xff1a;选项 : A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)globalVar在哪里&#xff1f;____ staticGlobalVar在哪里&#x…