当前位置:首页 > 其他 > 手搓顺序表实现栈 代码详解及新手教程——从原理到实现的完整指南

手搓顺序表实现栈 代码详解及新手教程——从原理到实现的完整指南

3个月前 (07-06)

一、简介和特点

顺序栈是一种基于数组实现的后进先出(LIFO)数据结构。通过动态数组管理存储空间,它具备以下特点:

1. 数组存储:数据连续存储,支持随机访问,访问效率高。

2. 动态扩容:当满时自动扩展容量(本实现采用翻倍扩容),避免溢出。

3. 操作简单:通过栈顶指针 top 管理元素入栈、出栈,逻辑清晰。

二、与其他相比的优点

相比链式栈:无需额外指针存储节点关系,内存利用率更高。

相比静态数组栈:动态扩容机制解决了固定容量限制,更灵活。

新手友好:代码简洁,核心逻辑集中在 add()、del()、select() 三个方法,易于理解。

三、实现步骤

1. 构造栈:传入参数 newsize 初始化容量,分配 new int[newsize] 创建数组。

2. 元素入栈:

    检查 top + 1 == size 是否栈满;

    若满,创建两倍容量新数组,复制原数据并释放旧空间;

    将元素存入 stack[top++],更新 top。

3. 删除元素:仅将 top 减1,不实际删除数据(节省开销)。

4. 获取栈顶:直接返回 stack[top - 1],不修改栈状态。

四、代码及注释

#include <iostream>
using namespace std;

// 定义 Stack 类
class Stack {
private:
    int top;         // 栈顶指针,存储当前栈顶元素的下标(初始化为0)
    int* stack;      // 指向栈的指针,动态分配数组存储数据
    int size = 0;    // 栈的当前容量(初始为空,由构造函数传入)

public:
    // 构造函数:初始化栈的容量
    Stack(int newsize) {
        top = 0;          // 栈顶初始化为0(空栈)
        size = newsize;   // 设置栈的初始容量
        stack = new int[newsize];  // 动态分配内存,创建数组
    }

    // 添加元素到栈顶
    void add(int data) {
        // 检查栈是否已满(top+1 == size 表示下一个位置超出容量)
        if (top + 1 == size) {
            // 栈满时扩容:创建两倍容量的新数组
            int* tmp = new int[size * 2];
            // 将原数组元素复制到新数组
            for (int i = 0; i < size; i++) {
                tmp[i] = stack[i];
            }
            // 释放原数组内存
            delete[] stack;
            // 更新栈指针和容量
            stack = tmp;
            size *= 2;
        }
        // 将元素添加到栈顶(top指向的位置),并更新栈顶指针
        stack[top++] = data;
    }

    // 删除栈顶元素(不移除数据,仅调整top指针)
    void del() {
        top = max(0, top - 1);  // 防止top减到负数,确保至少为0
    }

    // 获取栈顶元素(不删除)
    int select() {
        return stack[top - 1];  // 返回当前栈顶元素
    }
};


五、总结

顺序栈适合需要频繁后进先出操作的场景(如表达式计算、函数调用模拟等)。本实现通过动态扩容平衡了空间与效率,但需注意:

    1.手动管理内存时,程序结束前应释放 stack 避免泄漏。

    2.扩容机制可能带来额外开销,实际应用可调整策略优化。

对新手而言,掌握其原理是理解数据结构与算法的基础,建议结合调试工具逐步分析执行流程。

参考:顺序表实现栈

原创内容 转载请注明出处

分享给朋友:

相关文章

LeetCode 537题解:复数乘法的C++高效实现与代码解析

LeetCode 537题解:复数乘法的C++高效实现与代码解析

一、题目解读LeetCode 537题要求实现两个复数的乘法,输入为形如"a+bi"的字符串,需输出乘积的复数形式。题目核心在于解析字符串中的实部与虚部,并应用复数乘法公式计算结果...

手把手教你用链表实现栈:从步骤讲解到实战应用(新手友好版)

一、简介和特点链表栈是一种基于链表实现的数据结构,结合了栈的“先进后出(LIFO)”特性和链表的动态内存分配优势。相比数组实现的栈,链表栈无需提前指定固定容量,可动态扩展,插入和删除操作效率高,尤其适...

洛谷P3369题解:Treap动态数据结构详解与代码实现

洛谷P3369题解:Treap动态数据结构详解与代码实现

一、题目解读洛谷P3369题要求处理动态区间内的数据操作,涉及插入、删除及查询等。题目难点在于维护数据的动态平衡与高效查找,传统数据结构难以满足其性能需求。因此,需采用具有随机化平衡特性的Treap(...

力扣第7题整数反转:简洁高效的C++代码

力扣第7题整数反转:简洁高效的C++代码

一、题目解读LeetCode第7题“整数反转”要求将给定整数x反转后返回,但需考虑整数溢出的边界情况。例如,输入123反转后为321,但若x为1534236469,反转后超出int范围则需返回0。题目...

牛客16444题解析:公交线路最短路径算法优化(BFS+双向映射)

牛客16444题解析:公交线路最短路径算法优化(BFS+双向映射)

一、题目解读本题要求求解一个公交线路网络中的最短路径问题:给定n个站点和m条公交线路,每条线路包含多个站点,求从起点站1到终点站n的最小换乘次数。题目需高效处理站点与线路的双向关联,并优化路径搜索效率...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。