从C语言到C++_19(容器适配器+stack和queue模拟实现+优先级队列priority_queue)(上)

简介: 从C语言到C++_19(容器适配器+stack和queue模拟实现+优先级队列priority_queue)

1. 容器适配器

1.1 什么是适配器

想了解这里的 "适配器",我们先去看看电源适配器:

【百度百科】电源适配器又叫外置电源,是小型便携式电子设备及电子电器的供电电压变换设备,常见于手机、液晶显示器和笔记本电脑等小型电子产品上。

电源适配器是进行 "转换" 的,它本质上可以理解为是一个变压器

标准家庭用电电压为220V,我们设备用电其实并不需要这么高,

而电源适配器可以使较高的交流电压降低到合适于手机电池的直流工作电压。

也就是说,电源适配器是用来 "转换" 的。

再看看容器适配器:

一种用来修饰容器,仿函数或者迭代器的接口的东西。

配接器修改类的接口,使原来不相互匹配的两个类可以相互匹配,进行合作。

1.2 STL标准库中stackqueue的底层结构

前一篇我们提到:虽然stackqueue中也可以存放元素,

但在STL中并没有将其划分在容器的行列,而是将其称为容器适配

这是因为stack和队列只是对其他容器的接口进行了包装,

STLstackqueue默认使用deque,比如:

deque(双端队列,后面讲)(可以手动换成其它的)

2. stack和queue的模拟实现

2.1 stack模拟实现

我们以前已经用C语言写过了一个数组栈:

数据结构与算法⑧(第三章_上)栈的概念和实现(力扣:20. 有效的括号)_GR C的博客-CSDN博客

数组栈和链式栈

实现栈无非就两种结构:数组结构 和 链式结构,两种结构都可以实现。


数组栈和链式栈哪种结构更好?


相对而言数组的结构实现更优,尾插尾删的效率高,缓存利用率高,它的唯一缺点只是增容,


但是增容1次扩2倍对栈来说本身就比较合理,是无伤大雅的。而链式栈虽然不会空间浪费,


用一个 malloc 申请一个,但是链式栈存在一个致命的缺点:单链表不好出数据,


必须要实现双向链表,否则尾上删除数据将会异常麻烦。


如果硬要使用链式栈:


① 如果用尾做栈顶,尾插尾删,要设计成双向链表,否则删数据效率低。


② 如果用头做栈顶,头插头删,就可以设计成单链表。

在C++我们就可以直接用vector实现数组栈了,体会一下C++的方便,直接放stack.h了:

#pragma once
#include <iostream>
#include <vector>
using namespace std;
 
namespace rtx
{
  template<class T>
  class stack
  {
  public:
    void push(const T& x)
    {
      _con.push_back(x);
    }
    void pop()
    {
      _con.pop_back();
    }
    T& top()
    {
      return _con.back();
    }
    const T& top() const
    {
      return _con.pop_back();
    }
    bool empty() const
    {
      return _con.empty();
    }
    size_t size() const
    {
      return _con.size();
    }
  private:
    vector<T> _con;
  };
}

测试Test.c:

#include "Stack.h"
 
void test_stack()
{
    rtx::stack<int> st;
    st.push(1);
    st.push(2);
    st.push(3);
    st.push(4);
    st.push(5);
 
    cout << "st.size() = " << st.size() << endl;
    while (!st.empty())
    {
        cout << st.top() << " "; // 后进先出
        st.pop();
    }
    cout << endl;
}
 
int main()
{
    test_stack();
 
    return 0;
}

我们这里复用了vector,这是不是适配器呢?

这里并不是,因为底层已经写死了,它就是数组栈,如果我想要一个链式栈呢?

模板的方便又来了:

#pragma once
#include <iostream>
#include <vector>
using namespace std;
 
namespace rtx
{
  template<class T, class Container>
  class stack
  {
  public:
    void push(const T& x)
    {
      _con.push_back(x);
    }
    void pop()
    {
      _con.pop_back();
    }
    T& top()
    {
      return _con.back();
    }
    const T& top() const
    {
      return _con.pop_back();
    }
    bool empty() const
    {
      return _con.empty();
    }
    size_t size() const
    {
      return _con.size();
    }
  private:
    //vector<T> _con;
    Container _con;
  };
}
#include "Stack.h"
 
void test_stack()
{
    rtx::stack<int, vector<int>> st;
    st.push(1);
    st.push(2);
    st.push(3);
    st.push(4);
    st.push(5);
 
    cout << "st.size() = " << st.size() << endl;
    while (!st.empty())
    {
        cout << st.top() << " "; // 后进先出
        st.pop();
    }
    cout << endl;
}
 
int main()
{
    test_stack();
 
    return 0;
}

如果我们要链式栈:把显示传的vector换成list(包一下头文件):

前面说到,STL里面stack和queue的默认适配器是deque

把其它头文件移到Test.c ,Stack.h的最终就是这样的:

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

2.2 queue的模拟实现

deque等下讲,这里先放queue的模拟实现,经过前面的学习,直接放了:

Queue.h:

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

Test.c:

#include <iostream>
#include <vector>
#include <list>
#include <string>
using namespace std;
 
#include "Stack.h"
#include "Queue.h"
 
void test_stack()
{
    rtx::stack<int> st;
    st.push(1);
    st.push(2);
    st.push(3);
    st.push(4);
    st.push(5);
 
    cout << "st.size() = " << st.size() << endl;
    while (!st.empty())
    {
        cout << st.top() << " "; // 后进先出
        st.pop();
    }
    cout << endl;
}
void test_queue()
{
    rtx::queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    q.push(4);
    q.push(5);
 
    cout << "q.size() = " << q.size() << endl;
    while (!q.empty())
    {
        cout << q.front() << " "; // 先进先出
        q.pop();
    }
    cout << endl;
}
int main()
{
    test_stack();
    test_queue();
 
    return 0;
}

值得注意的是这里的queue不能显示地传vector,因为vector没有头删。

从C语言到C++_19(容器适配器+stack和queue模拟实现+优先级队列priority_queue)(中):https://developer.aliyun.com/article/1521888?spm=a2c6h.13148508.setting.25.712b4f0eDngT44


目录
相关文章
|
3天前
|
设计模式 C++ 容器
c++中的Stack与Queue
c++中的Stack与Queue
|
25天前
|
C++ 容器
【c++丨STL】stack和queue的使用及模拟实现
本文介绍了STL中的两个重要容器适配器:栈(stack)和队列(queue)。容器适配器是在已有容器基础上添加新特性或功能的结构,如栈基于顺序表或链表限制操作实现。文章详细讲解了stack和queue的主要成员函数(empty、size、top/front/back、push/pop、swap),并提供了使用示例和模拟实现代码。通过这些内容,读者可以更好地理解这两种数据结构的工作原理及其实现方法。最后,作者鼓励读者点赞支持。 总结:本文深入浅出地讲解了STL中stack和queue的使用方法及其模拟实现,帮助读者掌握这两种容器适配器的特性和应用场景。
56 21
|
3月前
|
存储 设计模式 C++
【C++】优先级队列(容器适配器)
本文介绍了C++ STL中的线性容器及其适配器,包括栈、队列和优先队列的设计与实现。详细解析了`deque`的特点和存储结构,以及如何利用`deque`实现栈、队列和优先队列。通过自定义命名空间和类模板,展示了如何模拟实现这些容器适配器,重点讲解了优先队列的内部机制,如堆的构建与维护方法。
63 0
|
4月前
|
存储 算法 调度
【C++打怪之路Lv11】-- stack、queue和优先级队列
【C++打怪之路Lv11】-- stack、queue和优先级队列
62 1
|
6天前
|
Ubuntu API 网络虚拟化
ubuntu22 编译安装docker,和docker容器方式安装 deepseek
本脚本适用于Ubuntu 22.04,主要功能包括编译安装Docker和安装DeepSeek模型。首先通过Apt源配置安装Docker,确保网络稳定(建议使用VPN)。接着下载并配置Docker二进制文件,创建Docker用户组并设置守护进程。随后拉取Debian 12镜像,安装系统必备工具,配置Ollama模型管理器,并最终部署和运行DeepSeek模型,提供API接口进行交互测试。
129 15
|
1月前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
160 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
1月前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
203 11
|
2月前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
96 8
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
2月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
177 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
2月前
|
关系型数据库 应用服务中间件 PHP
实战~如何组织一个多容器项目docker-compose
本文介绍了如何使用Docker搭建Nginx、PHP和MySQL的环境。首先启动Nginx容器并查看IP地址,接着启动Alpine容器并安装curl测试连通性。通过`--link`方式或`docker-compose`配置文件实现服务间的通信。最后展示了Nginx配置文件和PHP代码示例,验证了各服务的正常运行。
84 3
实战~如何组织一个多容器项目docker-compose

热门文章

最新文章