
C++ 标准库中的 `<stack>` 头文件提供了 `stack` 容器适配器，用于实现栈数据结构（后进先出，LIFO）。以下是其详细用法总结：


### 一、基本概念
- **容器适配器**：`stack` 并非独立容器，而是包装了其他容器（如 `deque`、`vector`、`list`），通过限制接口使其成为栈。
- **默认底层容器**：`std::deque`（双端队列），可显式指定其他顺序容器（需支持 `back()`、`push_back()`、`pop_back()` 操作）。


### 二、头文件与声明
```cpp
#include <stack>  // 必需头文件
using namespace std;

// 声明方式：stack<数据类型, 底层容器类型> 栈名;
stack<int> s;                  // 默认底层容器为 deque<int>
stack<string, vector<string>> s_vec;  // 底层容器为 vector<string>
stack<double, list<double>> s_list;   // 底层容器为 list<double>
```


### 三、常用成员函数

#### 1. 元素操作
| 函数                | 描述                                                                 |
|---------------------|----------------------------------------------------------------------|
| `push(value)`       | 将元素 `value` 压入栈顶（调用底层容器的 `push_back()`）。            |
| `pop()`             | 弹出栈顶元素（不返回值，调用底层容器的 `pop_back()`）。             |
| `top()`             | 返回栈顶元素的引用（若栈为空，调用会导致未定义行为）。               |
| `emplace(args...)`  | （C++11+）在栈顶直接构造元素（避免临时对象，参数为构造函数参数包）。|

**示例**：
```cpp
stack<int> s;
s.push(10);       // 栈：[10]
s.emplace(20);    // 栈：[10, 20]（等价于 push(20)）
cout << s.top();  // 输出 20
s.pop();          // 栈：[10]
```


#### 2. 容量与状态
| 函数            | 描述                                      |
|-----------------|-------------------------------------------|
| `empty()`       | 检查栈是否为空，空则返回 `true`，否则 `false`。 |
| `size()`        | 返回栈中元素个数（调用底层容器的 `size()`）。  |

**示例**：
```cpp
cout << s.empty();  // 输出 0（非空）
cout << s.size();   // 输出 1
```


#### 3. 底层容器访问（C++17+）
| 函数            | 描述                                  |
|-----------------|---------------------------------------|
| `get_allocator()`| 返回底层容器的分配器。                |
| `container()`    | （C++20+）返回底层容器的引用（需 `#include <iterator>`）。 |

**示例**：
```cpp
stack<int>::container_type& cnt = s.container();  // 获取底层 deque<int>&
```


### 四、自定义底层容器
`stack` 支持的底层容器需满足以下条件：
- 支持 `back()` 访问最后一个元素。
- 支持 `push_back()` 向末尾添加元素。
- 支持 `pop_back()` 从末尾删除元素。

常用可选容器：
- `deque<T>`（默认，效率均衡）
- `vector<T>`（适合随机访问，但动态扩容可能导致重新分配内存）
- `list<T>`（适合频繁插入/删除，内存非连续）

**示例：使用 vector 作为底层容器**
```cpp
stack<int, vector<int>> s_vec;
s_vec.push(1);
s_vec.push(2);
```


### 五、自定义数据类型
当栈中存储自定义类对象时，需确保类支持拷贝构造或移动构造（若使用 `emplace`，需支持直接构造）。

**示例：存储自定义结构体**
```cpp
struct Point {
    int x, y;
    Point(int a, int b) : x(a), y(b) {}
};

stack<Point> s_points;
s_points.emplace(1, 2);       // 直接构造对象压栈
Point p(3, 4);
s_points.push(p);              // 拷贝构造压栈
```


### 六、非成员函数
`stack` 支持关系运算符（`==`, `!=`, `<`, `<=`, `>`, `>=`），比较规则：
- 首先比较底层容器的大小，若大小不同，按大小判断。
- 若大小相同，逐个元素比较（调用元素的对应运算符）。

```cpp
stack<int> s1, s2;
s1.push(1); s2.push(1);
cout << (s1 == s2);  // 输出 1（相等）
```


### 七、注意事项
1. **线程安全**：标准库 `stack` 非线程安全，多线程环境需自行加锁。
2. **空栈操作风险**：调用 `top()` 或 `pop()` 前需用 `empty()` 检查，否则可能导致程序崩溃。
3. **底层容器特性**：不同底层容器影响性能，例如 `vector` 的 `pop_back()` 均摊 O(1)，`list` 的 `pop_back()` 严格 O(1)。
4. **迭代器限制**：`stack` 不暴露迭代器，无法直接遍历元素（需弹出元素访问）。


### 八、完整示例
```cpp
#include <stack>
#include <iostream>
#include <vector>

using namespace std;

int main() {
    // 基本操作
    stack<int> s;
    s.push(10);
    s.push(20);
    cout << "栈顶元素：" << s.top() << endl;  // 20
    s.pop();
    cout << "弹出后栈顶：" << s.top() << endl; // 10

    // 使用 vector 作为底层容器
    stack<string, vector<string>> s_str;
    s_str.emplace("hello");
    s_str.emplace("world");
    while (!s_str.empty()) {
        cout << s_str.top() << " ";  // 输出 "world hello"
        s_str.pop();
    }

    // 自定义类型
    struct Data {
        int val;
        Data(int v) : val(v) {}
    };
    stack<Data> s_data;
    s_data.emplace(42);
    cout << "自定义数据：" << s_data.top().val << endl;  // 42

    return 0;
}
```


### 总结
`stack` 是简单高效的 LIFO 容器，通过包装底层容器实现。使用时需注意：
- 明确底层容器的选择与性能 trade-off。
- 确保空栈检查，避免未定义行为。
- 利用 `emplace` 优化元素构造效率。

通过合理组合底层容器和成员函数，可满足大多数栈结构的应用场景。在C++里，`#include <stack>`引入的标准库提供了`std::stack`容器适配器，它遵循后进先出（LIFO）原则，适用于像函数调用栈、回溯算法等场景。下面是对`std::stack`标准库详细用法的总结。

### 1. 头文件包含
要使用`std::stack`，得包含`<stack>`头文件：
```cpp
#include <stack>
```

### 2. 声明与初始化
可使用任意支持随机访问迭代器的容器（如`std::vector`、`std::deque`、`std::list`）来实例化`std::stack`，默认容器是`std::deque`。
```cpp
#include <stack>
#include <vector>

// 默认使用 std::deque 作为底层容器
std::stack<int> stack1;

// 使用 std::vector 作为底层容器
std::stack<int, std::vector<int>> stack2;
```

### 3. 常用成员函数

#### 3.1 `push()`
把元素添加到栈顶。
```cpp
#include <iostream>
#include <stack>

int main() {
    std::stack<int> myStack;
    myStack.push(10);
    myStack.push(20);
    return 0;
}
```

#### 3.2 `pop()`
移除栈顶元素，但不返回其值。
```cpp
#include <iostream>
#include <stack>

int main() {
    std::stack<int> myStack;
    myStack.push(10);
    myStack.push(20);
    myStack.pop(); // 移除 20
    return 0;
}
```

#### 3.3 `top()`
返回栈顶元素的引用。
```cpp
#include <iostream>
#include <stack>

int main() {
    std::stack<int> myStack;
    myStack.push(10);
    myStack.push(20);
    std::cout << "Top element: " << myStack.top() << std::endl; // 输出 20
    return 0;
}
```

#### 3.4 `empty()`
判断栈是否为空，若为空则返回`true`，反之返回`false`。
```cpp
#include <iostream>
#include <stack>

int main() {
    std::stack<int> myStack;
    if (myStack.empty()) {
        std::cout << "Stack is empty." << std::endl;
    }
    return 0;
}
```

#### 3.5 `size()`
返回栈中元素的数量。
```cpp
#include <iostream>
#include <stack>

int main() {
    std::stack<int> myStack;
    myStack.push(10);
    myStack.push(20);
    std::cout << "Stack size: " << myStack.size() << std::endl; // 输出 2
    return 0;
}
```

### 4. 示例代码
以下是一个综合示例，展示了`std::stack`的基本用法：
```cpp
#include <iostream>
#include <stack>

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

    // 入栈操作
    myStack.push(1);
    myStack.push(2);
    myStack.push(3);

    // 输出栈顶元素
    std::cout << "Top element: " << myStack.top() << std::endl;

    // 出栈操作
    myStack.pop();
    std::cout << "After pop, top element: " << myStack.top() << std::endl;

    // 检查栈是否为空
    if (!myStack.empty()) {
        std::cout << "Stack is not empty." << std::endl;
    }

    // 输出栈的大小
    std::cout << "Stack size: " << myStack.size() << std::endl;

    return 0;
}
```

### 5. 复杂度分析
- `push()`：平均时间复杂度为$O(1)$。
- `pop()`：平均时间复杂度为$O(1)$。
- `top()`：时间复杂度为$O(1)$。
- `empty()`：时间复杂度为$O(1)$。
- `size()`：时间复杂度为$O(1)$。

总之，`std::stack`是一个方便的容器适配器，能轻松实现栈的基本操作。 