顺序栈(动态数组实现) 超详细解析(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)


相关推荐
码匠许师傅3 分钟前
【C++三方组件】Asio 下篇:C++20 协程版 TCP 客户端与服务端
c++·tcp/ip·c++20
sunburn-22 分钟前
Java 排序算法详细教学:从冒泡排序到快速排序
java·开发语言·数据结构·ide·算法
一只旭宝31 分钟前
【C++复习】四种类型转换 + 常见设计模式 + Redis/MySQL(后端面试复习完整版)
c++·redis·笔记·mysql·设计模式
rhett. li36 分钟前
用 AI 写 C++ 桌面 UI:TRAE + nim_duilib 实战指南
c++·人工智能·ui
ShineWinsu1 小时前
对于Redis:Redis特性以及应用场景的解析
linux·c++·redis·缓存·高并发·分布式系统·key-value
bksczm1 小时前
零基础面试题1
jvm·数据结构·算法
sogw-三叶草️1 小时前
LeetCode206. 反转链表
数据结构·链表
-森屿安年-1 小时前
买卖股票的最佳时机
c++·贪心算法
2601_962218611 小时前
C++ AVL树概念与实现详解
开发语言·c++
炘爚1 小时前
C++(STL)
开发语言·c++