以下是一个基于C++实现的动态扩容栈的完整代码,包含初始化、压栈、弹栈、获取栈顶元素等基本操作,并附带详细注释。代码符合现代C++规范,可直接编译运行:
#include <iostream>
#include <stdexcept>
template <typename T>
class DynamicStack {
private:
T* elements; // 存储元素的动态数组
int capacity; // 当前分配的存储容量
int topIndex; // 栈顶元素索引(-1表示空栈)
void resize(int newCapacity) { // 动态调整容量
T* newArray = new T[newCapacity];
for (int i = 0; i <= topIndex; ++i) {
newArray[i] = elements[i];
}
delete[] elements;
elements = newArray;
capacity = newCapacity;
}
public:
// 构造函数(初始容量为4)
DynamicStack() : capacity(4), topIndex(-1) {
elements = new T[capacity];
}
// 析构函数
~DynamicStack() {
delete[] elements;
}
// 压栈操作
void push(const T& value) {
if (topIndex == capacity - 1) { // 空间不足时自动扩容
resize(capacity * 2);
}
elements[++topIndex] = value;
}
// 弹栈操作
T pop() {
if (isEmpty()) {
throw std::underflow_error("Stack underflow");
}
T value = elements[topIndex--];
// 空间利用率不足25%时自动缩容
if (topIndex < capacity / 4 && capacity > 4) {
resize(capacity / 2);
}
return value;
}
// 获取栈顶元素
T& top() {
if (isEmpty()) {
throw std::out_of_range("Stack is empty");
}
return elements[topIndex];
}
// 判断栈是否为空
bool isEmpty() const {
return topIndex == -1;
}
// 获取元素数量
int size() const {
return topIndex + 1;
}
// 获取当前容量(调试用)
int getCapacity() const {
return capacity;
}
// 禁用拷贝构造和赋值操作
DynamicStack(const DynamicStack&) = delete;
DynamicStack& operator=(const DynamicStack&) = delete;
};
int main() {
try {
DynamicStack<int> stack;
// 压栈测试
for (int i = 1; i <= 10; ++i) {
stack.push(i * 10);
std::cout << "压入: " << i*10
<< " 大小: " << stack.size()
<< " 容量: " << stack.getCapacity() << std::endl;
}
// 查看栈顶元素
std::cout << "\n当前栈顶元素: " << stack.top() << std::endl;
// 弹栈测试
while (!stack.isEmpty()) {
std::cout << "弹出: " << stack.pop()
<< " 剩余大小: " << stack.size()
<< " 容量: " << stack.getCapacity() << std::endl;
}
// 测试异常情况
stack.pop(); // 触发下溢异常
}
catch (const std::exception& e) {
std::cerr << "\n异常捕获: " << e.what() << std::endl;
}
return 0;
}
代码特性说明:
- 动态扩容机制:当栈满时容量自动翻倍,空间利用率低于25%时自动缩容,平衡时间和空间效率
- 异常处理:使用标准异常类型
std::underflow_error
和std::out_of_range
处理非法操作 - 内存安全:
• 析构函数自动释放内存
• 禁用拷贝构造函数和赋值操作防止浅拷贝问题 - 泛型支持:通过模板类支持任意数据类型存储
- 调试信息:提供容量查询接口用于观察动态扩容过程
运行结果示例:
压入: 10 大小: 1 容量: 4
压入: 20 大小: 2 容量: 4
压入: 30 大小: 3 容量: 4
压入: 40 大小: 4 容量: 4
压入: 50 大小: 5 容量: 8
...
压入: 100 大小: 10 容量: 16
当前栈顶元素: 100
弹出: 100 剩余大小: 9 容量: 16
弹出: 90 剩余大小: 8 容量: 16
...
弹出: 20 剩余大小: 1 容量: 4
弹出: 10 剩余大小: 0 容量: 2
异常捕获: Stack underflow
代码优化点:
- 缩容策略:在弹出元素后检查空间利用率,防止内存浪费
- 移动语义:可添加移动构造函数提升大对象操作效率
- 迭代器:可通过实现begin/end方法支持范围遍历
- 批量操作:可扩展push/pop多个元素的方法
该实现相比传统固定容量栈具有更好的内存利用率,相比STL的stack,提供了更直观的扩容策略可视化能力。