当前位置: 首页 > article >正文

基于STL的自定义栈与队列实现:灵活选择底层容器的模板设计

文章目录

  • 代码
  • 模板设计
  • 主要成员函数
  • 底层容器的选择
  • 模板设计
  • 底层容器的选择
  • 关于stack的示例代码
  • 关于queue的示例代码

前言:

在本文中,我们将分析一个模拟C++标准模板库(STL)栈的自定义实现以及模仿C++标准模板库(STL)队列的自定义实现。该stack类模板允许在底层容器的选择上具有灵活性、该queue类模板采用灵活的容器选择机制,默认使用std::deque作为底层容器,这与STL设计相似。接下来,我们将深入研究代码的结构、功能,以及使用模板和容器组合在C++中实现的优势。

代码

这是在Stack命名空间下的主要类定义:

namespace Stack
{
    template<class T, class Container>
    class stack
    {
    public:
        void push(const T& x) { _con.push_back(x); }
        void pop() { _con.pop_back(); }
        const T& top() const { return _con.back(); }
        size_t size() const { return _con.size(); }
        bool empty() const { return _con.empty(); }
    
    private:
        Container _con;
    };
}

模板设计

该类是一个模板,接受两个参数:
T:存储在栈中的元素类型。
Container:底层容器类型,用于管理栈元素的存储。
这种设计使我们能够自定义底层的存储容器,允许使用std::vector、std::list或std::deque作为底层数据结构。在标准库中,std::stack默认使用std::deque作为底层容器,因为它在两端插入和移除元素时的效率较高。

主要成员函数

让我们逐一了解主要的成员函数:

push(const T& x):用于将一个元素x压入栈顶。此实现使用了push_back函数,因为无论使用哪种容器,我们都希望在容器末尾添加新元素。

pop():用于移除栈顶元素。与push类似,此处使用pop_back,因为需要从容器的末尾移除元素。

top() const:返回栈顶元素的常量引用。这是只读访问,因为栈顶元素不能通过top()修改。

size() const:返回栈中的元素数量,直接调用容器的size()函数。

empty() const:用于检查栈是否为空,直接调用容器的empty()函数。

底层容器的选择

在这个实现中,底层容器的选择灵活。例如:
std::vector:可以用于存储连续内存中的栈,但当栈中的元素较多时,可能会带来内存的重新分配开销。
std::list:是链式存储结构,不支持随机访问,但在频繁插入和删除操作时性能较优。
std::deque:是双端队列,既支持随机访问,又可以在两端进行高效的插入和删除操作,是STL中std::stack的默认容器。
小结
该stack模板类通过组合不同的容器类型实现了灵活的栈结构,符合STL设计原则。在实际使用中,根据需求选择合适的底层容器,可以进一步优化栈的性能。

这是在Queue命名空间下的queue类定义:

namespace Queue
{
    template<class T, class Container = std::deque<T>>
    class queue
    {
    public:
        void push(const T& x) { _con.push_back(x); }
        void pop() { _con.pop_front(); }
        const T& front() const { return _con.front(); }
        const T& back() const { return _con.back(); }
        size_t size() const { return _con.size(); }
        bool empty() const { return _con.empty(); }
    
    private:
        Container _con;
    };
}

模板设计

该类是一个模板,接受两个参数:
T:存储在队列中的元素类型。
Container:底层容器类型,用于存储队列元素,默认使用std::deque。
这种设计允许我们在实现队列时选择不同的容器,如std::deque、std::vector或std::list。然而,std::deque是STL中默认的底层容器,因其支持在两端快速插入和删除元素,非常适合队列的FIFO(First In, First Out)特性。

主要成员函数解析
以下是queue类中的核心成员函数:

void push(const T& x)
push函数将元素x添加到队列末尾。此函数调用_con.push_back(x),无论底层容器是什么类型,都确保新元素添加到队列的“尾部”。

void pop()
pop函数移除队列的第一个元素。它调用_con.pop_front(),遵循队列的FIFO特性,将队首元素出队。这种操作在std::deque和std::list中效率较高,而在std::vector中效率相对较低。

const T& front() const
front函数返回队列首元素的常量引用。由于是常量引用,用户可以读取但不能修改队首元素。

const T& back() const
back函数返回队列尾元素的常量引用。用户可以读取队列中的最后一个元素,但不能通过此方法修改它。

size_t size() const
size函数返回队列中元素的数量,直接调用底层容器的size()函数。

bool empty() const
empty函数检查队列是否为空,直接调用底层容器的empty()函数。

底层容器的选择

在该实现中,可以选择不同的容器作为底层数据结构,以下是常见的选择及其特点:
std::deque:STL中std::queue的默认容器。支持两端快速插入和删除,非常适合队列的特性。
std::list:链表结构,允许在两端常数时间内插入和删除元素,适用于需要频繁插入和删除的场景。
std::vector:虽然可以作为底层容器,但由于在队首插入和删除元素效率较低,通常不推荐在队列中使用。

关于stack的示例代码

#include "stack.h"
#include <vector>
#include <list>
#include <iostream>

int main() {
    // 使用 std::vector 作为底层容器的栈
    bit::stack<int, std::vector<int>> vector_stack;
    vector_stack.push(10);
    vector_stack.push(20);
    vector_stack.push(30);
    vector_stack.pop();  // 移除栈顶元素
    std::cout << "Top element in vector-based stack: " << vector_stack.top() << std::endl;  // 输出栈顶元素
    std::cout << "Stack size: " << vector_stack.size() << std::endl;  // 输出栈的大小

    // 使用 std::list 作为底层容器的栈
    bit::stack<int, std::list<int>> list_stack;
    list_stack.push(40);
    list_stack.push(50);
    list_stack.push(60);
    list_stack.pop();  // 移除栈顶元素
    std::cout << "Top element in list-based stack: " << list_stack.top() << std::endl;  // 输出栈顶元素
    std::cout << "Stack size: " << list_stack.size() << std::endl;  // 输出栈的大小

    return 0;
}

关于queue的示例代码

#include "queue.h"
#include <deque>
#include <list>
#include <vector>
#include <iostream>

int main() {
    bit::queue<int, std::deque<int>> deque_queue;
    deque_queue.push(10);
    deque_queue.push(20);
    deque_queue.push(30);
    deque_queue.pop();
    std::cout << "Front element in deque-based queue: " << deque_queue.front() << std::endl;

    bit::queue<int, std::list<int>> list_queue;
    list_queue.push(40);
    list_queue.push(50);
    list_queue.push(60);
    list_queue.pop();
    std::cout << "Front element in list-based queue: " << list_queue.front() << std::endl;

    return 0;
}

http://www.kler.cn/a/377624.html

相关文章:

  • 【P2-9】ESP8266 WIFI模块在STA模式下作为TCP客户端上电自动进入透传数据模式
  • Chrome 130 版本开发者工具(DevTools)更新内容
  • github - ssh 配置 key、下载repo
  • 相机硬触发
  • 2024年9月电子学会青少年软件编程Python等级考试(四级)真题试卷
  • (七)Python运算符和优先级
  • 长度最小的子数组(滑动窗口)
  • cangjie仓颉程序设计-数据结构(四)
  • 无人机之远程指挥中心技术篇
  • 鸿蒙中的FA模型和Stage模型
  • 10.31.2024刷华为OD C题型
  • Scikit-learn和Keras简介
  • 为啥学习数据结构和算法
  • 最新整理:linux常见面试题库
  • 代码源NOIP DAY2 T1 LIS和LDS题解
  • Web Broker(Web服务应用程序)入门教程(5)
  • 2181、合并零之间的节点
  • PostgreSQL 删除重复数据
  • 【Eclipse系列】eclipse快捷键和设置
  • 群控系统服务端开发模式-应用开发-业务架构逻辑开发第一轮测试
  • 性能测试|linux服务器搭建JMeter+Grafana+Influxdb监控可视化平台
  • 测试华为GaussDB(DWS)数仓,并通过APISQL快速将(表、视图、存储过程)发布为API
  • [LeetCode] 面试题08.01 三步问题
  • clion远程配置docker ros2
  • 3D区块多重渐变围栏
  • 【Linux】mnt命名空间-操作