0

0

C++ stack适配器 后进先出数据结构应用

P粉602998670

P粉602998670

发布时间:2025-08-20 10:10:02

|

207人浏览过

|

来源于php中文网

原创

C++ stack适配器基于vector、deque或list实现LIFO结构,提供push、pop、top操作,适用于括号匹配、表达式求值等场景,可通过自定义容器实现有界栈以满足特定需求。

c++ stack适配器 后进先出数据结构应用

C++

stack
适配器本质上是利用现有的容器(如
vector
deque
list
)来实现后进先出(LIFO)的数据结构。它提供了一种方便的方式来管理数据的进出顺序,常用于解决需要追踪最近操作或需要回溯算法的问题。

解决方案

C++

stack
适配器允许你使用标准容器作为底层存储,并提供
push
pop
top
等方法来实现栈的功能。

#include 
#include 
#include 

int main() {
    // 使用 vector 作为底层容器
    std::stack> myStack;

    myStack.push(10);
    myStack.push(20);
    myStack.push(30);

    std::cout << "Top element: " << myStack.top() << std::endl; // 输出: 30

    myStack.pop();
    std::cout << "Top element after pop: " << myStack.top() << std::endl; // 输出: 20

    std::cout << "Stack size: " << myStack.size() << std::endl; // 输出: 2

    return 0;
}

在这个例子中,我们使用了

std::vector
作为
std::stack
的底层容器。当然,你也可以选择
std::deque
std::list
,这取决于你的具体需求。例如,如果你需要频繁地在栈的底部进行操作,
std::deque
可能更合适,因为它在两端插入和删除元素的时间复杂度都是 O(1)。

如何选择 stack 的底层容器?性能考量

选择

stack
的底层容器时,需要考虑你的应用场景和性能需求。
vector
通常是默认的选择,因为它在大多数情况下提供了良好的性能。但是,
vector
在内存重新分配时可能会导致性能下降。
deque
在两端插入和删除元素时具有更好的性能,但访问中间元素可能会比较慢。
list
在插入和删除元素时具有最佳性能,但访问任何元素都需要线性时间。

立即学习C++免费学习笔记(深入)”;

例如,如果你的栈需要频繁地插入和删除元素,但很少访问中间元素,那么

list
可能是一个不错的选择。但是,如果你的栈需要频繁地访问中间元素,那么
vector
deque
可能会更好。

#include 
#include 
#include 

int main() {
    // 使用 deque 作为底层容器
    std::stack> myStack;

    myStack.push(10);
    myStack.push(20);
    myStack.push(30);

    std::cout << "Top element: " << myStack.top() << std::endl;

    return 0;
}

stack 在解决算法问题中的典型应用场景

stack
在解决算法问题中有很多典型的应用场景,例如:

魔法映像企业网站管理系统
魔法映像企业网站管理系统

技术上面应用了三层结构,AJAX框架,URL重写等基础的开发。并用了动软的代码生成器及数据访问类,加进了一些自己用到的小功能,算是整理了一些自己的操作类。系统设计上面说不出用什么模式,大体设计是后台分两级分类,设置好一级之后,再设置二级并选择栏目类型,如内容,列表,上传文件,新窗口等。这样就可以生成无限多个二级分类,也就是网站栏目。对于扩展性来说,如果有新的需求可以直接加一个栏目类型并新加功能操作

下载
  • 括号匹配: 检查表达式中的括号是否正确匹配。
  • 表达式求值: 将中缀表达式转换为后缀表达式,并计算表达式的值。
  • 深度优先搜索(DFS): 在图或树中进行深度优先搜索。
  • 函数调用栈: 模拟函数调用栈的行为。
  • 浏览器的前进/后退功能: 记录用户浏览历史。

下面是一个使用

stack
实现括号匹配的例子:

#include 
#include 
#include 

bool isMatching(const std::string& expression) {
    std::stack s;
    for (char c : expression) {
        if (c == '(' || c == '[' || c == '{') {
            s.push(c);
        } else if (c == ')' || c == ']' || c == '}') {
            if (s.empty()) {
                return false; // 缺少左括号
            }
            char top = s.top();
            s.pop();
            if ((c == ')' && top != '(') ||
                (c == ']' && top != '[') ||
                (c == '}' && top != '{')) {
                return false; // 括号不匹配
            }
        }
    }
    return s.empty(); // 所有括号都匹配
}

int main() {
    std::string expression1 = "([]{})";
    std::string expression2 = "([)]";

    std::cout << expression1 << " is matching: " << isMatching(expression1) << std::endl; // 输出: true
    std::cout << expression2 << " is matching: " << isMatching(expression2) << std::endl; // 输出: false

    return 0;
}

如何自定义 stack 的底层容器以满足特定需求

虽然

vector
deque
list
已经提供了很好的通用性,但在某些特殊情况下,你可能需要自定义
stack
的底层容器。例如,你可能需要使用一个固定大小的数组来实现一个有界栈,或者你可能需要使用一个自定义的内存分配器来优化内存使用。

要自定义

stack
的底层容器,你需要创建一个满足以下要求的类:

  • 提供
    push_back
    方法,用于在容器末尾添加元素。
  • 提供
    pop_back
    方法,用于删除容器末尾的元素。
  • 提供
    back
    方法,用于访问容器末尾的元素。
  • 提供
    empty
    方法,用于检查容器是否为空。
  • 提供
    size
    方法,用于获取容器的大小。

下面是一个使用固定大小数组实现有界栈的例子:

#include 
#include 

template 
class BoundedArray {
private:
    T data[N];
    size_t currentSize = 0;

public:
    void push_back(const T& value) {
        if (currentSize == N) {
            throw std::overflow_error("Stack overflow");
        }
        data[currentSize++] = value;
    }

    void pop_back() {
        if (currentSize == 0) {
            throw std::underflow_error("Stack underflow");
        }
        currentSize--;
    }

    T& back() {
        if (currentSize == 0) {
            throw std::underflow_error("Stack is empty");
        }
        return data[currentSize - 1];
    }

    bool empty() const {
        return currentSize == 0;
    }

    size_t size() const {
        return currentSize;
    }
};

int main() {
    std::stack> myStack;

    try {
        myStack.push(10);
        myStack.push(20);
        myStack.push(30);
        myStack.push(40);
        myStack.push(50);
        myStack.push(60); // 触发 overflow
    } catch (const std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl; // 输出: Stack overflow
    }

    std::cout << "Stack size: " << myStack.size() << std::endl; // 输出: 5

    return 0;
}

在这个例子中,我们创建了一个

BoundedArray
类,它使用一个固定大小的数组来存储数据。
BoundedArray
类提供了
push_back
pop_back
back
empty
size
方法,满足了
stack
对底层容器的要求。当栈满时,
push_back
方法会抛出一个
std::overflow_error
异常。当栈空时,
pop_back
back
方法会抛出一个
std::underflow_error
异常。

相关专题

更多
treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

529

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

5

2025.12.22

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

366

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

560

2023.08.10

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

387

2023.08.14

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

金山文档相关教程
金山文档相关教程

本专题整合了金山文档相关教程,阅读专题下面的文章了解更多详细操作。

29

2025.12.30

PS反选快捷键
PS反选快捷键

本专题整合了ps反选快捷键介绍,阅读下面的文章找到答案。

25

2025.12.30

表格中一行两行的方法
表格中一行两行的方法

本专题整合了表格中一行两行的相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.6万人学习

C 教程
C 教程

共75课时 | 3.8万人学习

C++教程
C++教程

共115课时 | 10.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号