顺序栈(动态数组实现) 超详细解析(C++ 语言 + 可直接运行)

前言

栈(Stack) 是一种 ** 后进先出(LIFO, Last In First Out)的线性数据结构。 它只允许在一端(栈顶)** 进行插入、删除操作,另一端(栈底)封闭。

栈的应用场景极广:

  • 函数调用栈

  • 表达式求值(计算器)

  • 括号匹配

  • 浏览器前进后退

  • 操作系统中断现场保护


一、顺序栈是什么?

顺序栈 = 用动态数组实现的栈

特点:

  • 底层是连续内存空间

  • 支持自动扩容(避免溢出)

  • 访问、插入、删除效率极高 O(1)

  • 实现简单、稳定、不易出错


二、顺序栈结构体设计及支持的操作

cpp 复制代码
#pragma once
#include<stdio.h>
typedef char ELEM_TYPE;       // 数据类型(可改为 int/double 等)
#define INITSIZE 10            // 初始容量

// 顺序栈结构体
struct Seq_Stack
{
    ELEM_TYPE* base;   // 动态数组起始地址
    int top;           // 栈顶指针(下标)
    int stacksize;     // 当前总容量
};

typedef struct Seq_Stack Seq_Stack;
typedef struct Seq_Stack* PSeq_Stack;
// 1. 初始化
void Init_Stack(Seq_Stack* ps);
// 2. 入栈
bool Push(Seq_Stack* ps, ELEM_TYPE val);
// 3. 出栈
bool Pop(Seq_Stack* ps);
// 4. 获取栈顶元素
ELEM_TYPE Top(Seq_Stack* ps);
// 5. 判空
bool Is_Empty(Seq_Stack* ps);
// 6. 判满
bool Is_Full(Seq_Stack* ps);
// 7. 扩容
static void Inc(Seq_Stack* ps);
// 8. 获取长度
int Get_Length(Seq_Stack* ps);
// 9. 清空
void Clear(Seq_Stack* ps);
// 10. 销毁(释放内存)
void Destroy(Seq_Stack* ps);
// 11. 打印
void Show(Seq_Stack* ps);

结构说明

  • base:指向动态分配的数组

  • top :始终指向下一个可入栈的位置

    • top == 0 → 空栈

    • top == stacksize → 栈满

  • stacksize:当前数组总容量(可扩容)


三、核心函数逐行精讲(最关键)

1. 初始化

cpp 复制代码
//初始化
void Init_Stack(Seq_Stack* ps)
{
	assert(ps != NULL);
    // 分配初始容量
	ps->base = (ELEM_TYPE*)malloc(INITSIZE * sizeof(ELEM_TYPE));
	if (ps->base == NULL)
		exit(1);
	ps->top = 0;
	ps->stacksize = INITSIZE;
}

作用:申请内存、设置栈空、容量初始化。


2. 入栈(Push)

cpp 复制代码
bool Push(Seq_Stack* ps, ELEM_TYPE val)
{
    assert(ps != NULL);
    // 满了就扩容 2 倍
    if (Is_Full(ps))
        Inc(ps);
    ps->base[ps->top] = val;
    ps->top++;
    return true;
}

时间复杂度 O(1)

自动扩容,永不溢出


3. 出栈(Pop)

cpp 复制代码
bool Pop(Seq_Stack* ps)
{
    assert(ps != NULL);
    if (Is_Empty(ps))
        return false;
    ps->top--;
    return true;
}

出栈不删除数据,只移动栈顶指针,高效!


4. 获取栈顶元素(Top)

cpp 复制代码
ELEM_TYPE Top(Seq_Stack* ps)
{
    assert(ps != NULL);
    if (Is_Empty(ps))
        exit(1);
    return ps->base[ps->top - 1];
}

5. 扩容函数(Inc)

cpp 复制代码
static void Inc(Seq_Stack* ps)
{
    assert(ps != NULL);
    ELEM_TYPE* tmp = (ELEM_TYPE*)realloc(ps->base, 2 * ps->stacksize * sizeof(ELEM_TYPE));
    if (tmp != NULL)
        ps->base = tmp;
    ps->stacksize *= 2;
}

自动扩容为原来的 2 倍,避免频繁申请内存。


6. 清空栈

cpp 复制代码
void Clear(Seq_Stack* ps)
{
    assert(ps != NULL);
    ps->top = 0;
}

不释放内存,只置空。


7. 销毁栈

cpp 复制代码
//销毁 需要free
void Destroy(Seq_Stack* ps)
{
	assert(ps != NULL);
	free(ps->base);
	ps->base = NULL;
	ps->top = ps->stacksize = 0;
}

必须销毁! 防止内存泄漏。


8. 打印栈

cpp 复制代码
void Show(Seq_Stack* ps)
{
	assert(ps != NULL);
	for (int i = 0; i < ps->top ; i++)
	{
		cout << ps->base[i] << " ";
	}
	cout << endl;
}

9. 判空、判满、获取有效长度值

cpp 复制代码
//判空
bool Is_Empty(Seq_Stack* ps)
{
	return ps->top == 0;
}
//判满
bool Is_Full(Seq_Stack* ps)
{
	return ps->top == ps->stacksize;
}
//获取有效长度值
int Get_Length(Seq_Stack* ps)
{
	assert(ps != NULL);
	return ps->top;
}

四、测试主函数(可直接运行)

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
#include<stdlib.h>
#include"顺序栈.h"

using namespace std;

int main()
{
	Seq_Stack head;
	Init_Stack(&head);
	Push(&head, 'A');
	Push(&head, 'B');
	Push(&head, 'C');
	Show(&head);
	cout << "长度: " << Get_Length(&head) << endl;
	cout << "栈顶元素: " << Top(&head) << endl;
	Pop(&head);
	Show(&head);
	return 0;
}

运行结果


五、顺序栈特点总结

连续内存,访问速度快

O (1) 入栈、出栈、取栈顶

动态扩容,不会溢出

实现简单、稳定

无野指针、无内存泄漏


六、高频考点(必背)

  1. **栈的特点是什么?**后进先出(LIFO)。

  2. 顺序栈和链式栈区别?

    • 顺序栈:连续内存、速度快、需扩容

    • 链式栈:离散内存、不用扩容、速度稍慢

  3. **顺序栈扩容为什么是 2 倍?**减少扩容次数,平衡时间与空间。

  4. top 指针的含义? 指向下一个可入栈的位置

  5. 清空和销毁的区别?

    • 清空:只置空,不释放内存

    • 销毁:释放所有内存

  6. 时间复杂度? 入栈、出栈、取栈顶:O(1)


相关推荐
漫霂2 小时前
二叉树的翻转
java·数据结构·算法
3秒一个大2 小时前
深入理解 JS 中的栈与堆:从内存模型到数据结构,再谈内存泄漏
前端·javascript·数据结构
念恒123063 小时前
Linux初识
linux·服务器·c++
旖-旎3 小时前
哈希表(存在重复元素)(3)
数据结构·c++·学习·算法·leetcode·散列表
计算机安禾3 小时前
【数据结构与算法】第39篇:图论(三):最小生成树——Prim算法与Kruskal算法
开发语言·数据结构·c++·算法·排序算法·图论·visual studio code
fish_xk3 小时前
c++内存管理
开发语言·c++·算法
汀、人工智能3 小时前
[特殊字符] 第77课:最长递增子序列
数据结构·算法·数据库架构·图论·bfs·最长递增子序列
澈2073 小时前
堆排序:高效构建大顶堆实战
数据结构·算法·排序算法
chh5634 小时前
C++--内存管理
java·c语言·c++·windows·学习·面试