【数据结构与算法】掌握顺序栈:从入门到实践

news2024/11/27 9:46:40

  

🌱博客主页:青竹雾色间.

🌱系列专栏:数据结构与算法

😘博客制作不易欢迎各位👍点赞+⭐收藏+➕关注

目录

前言

顺序栈的实现

初始化栈

判断栈空

判断栈满

入(进)栈

出栈

获取栈顶元素

示例代码

顺序栈的应用前景


前言

当你学习数据结构和算法时,顺序栈(Sequential Stack)是一个重要的概念。它是一种基于数组实现的栈结构,具有先进后出(LIFO)的特性。在本文中,我将介绍如何使用C语言实现顺序栈,并提供一些示例代码。

顺序栈的实现

首先,我们需要定义一个结构体来表示顺序栈:

#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int top;  // 栈顶指针
} SeqStack;

在上述代码中,我们定义了一个数组data用于存储栈中的元素,以及一个整数top表示栈顶指针。

接下来,我们可以实现一些基本的栈操作函数。

初始化栈

void initStack(SeqStack *stack) {
    stack->top = -1;  // 栈顶指针初始化为-1
}

该函数用于初始化一个空的顺序栈,将栈顶指针设为-1,表示栈为空。

判断栈空

int isEmpty(SeqStack stack) {
    return stack.top == -1;
}

上述代码用于检查顺序栈是否为空。如果栈顶指针为-1,表示栈中没有元素,返回1;否则返回0。

判断栈满

int isFull(SeqStack stack) {
    return stack.top == MAX_SIZE - 1;
}

该函数用于检查顺序栈是否已满。如果栈顶指针等于MAX_SIZE - 1,表示栈已满,返回1;否则返回0。

入(进)栈

int push(SeqStack *stack, int value) {
    if (isFull(*stack)) {
        printf("Stack is full. Cannot push element.\n");
        return 0;  // 入栈失败
    }
    
    stack->top++;  // 栈顶指针加1
    stack->data[stack->top] = value;  // 将元素存入栈顶位置
    return 1;  // 入栈成功
}

当要将一个元素压入栈时,首先检查栈是否已满。如果栈已满,则无法进行入栈操作,这称为栈上溢。如果栈未满,则将栈顶指针加1,并将新元素存储在栈顶指针指向的位置。

出栈

int pop(SeqStack *stack, int *value) {
    if (isEmpty(*stack)) {
        printf("Stack is empty. Cannot pop element.\n");
        return 0;  // 出栈失败
    }
    
    *value = stack->data[stack->top];  // 将栈顶元素赋值给value
    stack->top--;  // 栈顶指针减1
    return 1;  // 出栈成功
}

当要从栈中弹出一个元素时,首先检查栈是否为空。如果栈为空,则无法进行出栈操作,这称为栈下溢。如果栈非空,则返回栈顶指针指向的元素,并将栈顶指针减1,表示栈顶指向下一个元素。

获取栈顶元素

int getTop(SeqStack stack, int *value) {
    if (isEmpty(stack)) {
        printf("Stack is empty. No top element.\n");
        return 0;  // 获取失败
    }
    
    *value = stack.data[stack.top];  // 将栈顶元素赋值给value
    return 1;  // 获取成功
}

该函数用于获取栈顶元素的值,并将其赋给value。如果栈为空,会输出错误信息并返回0。

示例代码

下面是一个示例程序,演示了如何使用顺序栈进行一些基本操作:

#include <stdio.h>

#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int top;
} SeqStack;

void initStack(SeqStack *stack) {
    stack->top = -1;
}

int isEmpty(SeqStack stack) {
    return stack.top == -1;
}

int isFull(SeqStack stack) {
    return stack.top == MAX_SIZE - 1;
}

int push(SeqStack *stack, int value) {
    if (isFull(*stack)) {
        printf("Stack is full. Cannot push element.\n");
        return 0;
    }
    
    stack->top++;
    stack->data[stack->top] = value;
    return 1;
}

int pop(SeqStack *stack, int *value) {
    if (isEmpty(*stack)) {
        printf("Stack is empty. Cannot pop element.\n");
        return 0;
    }
    
    *value = stack->data[stack->top];
    stack->top--;
    return 1;
}

int getTop(SeqStack stack, int *value) {
    if (isEmpty(stack)) {
        printf("Stack is empty. No top element.\n");
        return 0;
    }
    
    *value = stack.data[stack.top];
    return 1;
}

int main() {
    SeqStack stack;
    initStack(&stack);
    
    push(&stack, 1);
    push(&stack, 2);
    push(&stack, 3);
    
    int top;
    getTop(stack, &top);
    printf("Top element: %d\n", top);
    
    int value;
    pop(&stack, &value);
    printf("Popped element: %d\n", value);
    
    getTop(stack, &top);
    printf("Top element: %d\n", top);
    
    return 0;
}

以上代码创建了一个顺序栈,并进行了一些入栈、出栈和获取栈顶元素的操作。运行该程序,输出如下:

Top element: 3
Popped element: 3
Top element: 2

这说明顺序栈的基本操作已经成功实现。

顺序栈的应用前景

  1. 表达式求值:顺序栈可以用于解析和计算数学表达式,如中缀表达式转后缀表达式,并利用后缀表达式进行求值。

  2. 括号匹配:顺序栈可以用于检查表达式中的括号是否匹配,如圆括号、方括号和花括号的配对情况。

  3. 浏览器历史记录:浏览器的后退功能可以使用顺序栈来实现。每当用户访问一个新的网页时,该网页的URL可以被推入栈中;当用户点击后退按钮时,可以从栈顶弹出上一个网页的URL。

  4. 撤销操作:在文本编辑器、图形绘制软件等应用程序中,顺序栈可以用于实现撤销操作。每当用户进行编辑或绘制操作时,相关的修改可以被推入栈中;当用户执行撤销操作时,可以从栈顶弹出最近的修改并还原到上一个状态。

  5. 函数调用:在程序执行过程中,函数调用的过程可以使用顺序栈来管理函数的调用关系和返回地址。

  6. 浏览器的前进功能:类似于后退功能,顺序栈可以用于实现浏览器的前进功能。每当用户执行后退操作时,访问的网页URL可以被推入栈中;当用户执行前进操作时,可以从栈顶弹出下一个网页的URL。

  7. 缓存管理:顺序栈可以用于缓存管理,特别是最近访问页面的缓存。当用户访问一个页面时,可以将其URL推入栈中,并根据缓存的大小限制栈的长度,当栈已满时,最久未访问的页面URL将被弹出。

这些只是顺序栈应用的一些例子,实际上,顺序栈在许多领域都有应用,如编译器设计、图形处理、操作系统等。顺序栈提供了一种简单而有效的数据结构,可以在许多问题中实现后进先出的操作。


通过以上所述 希望这篇文章对你学习数据结构和算法有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/629097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法系列 | 3】深入解析排序算法之插入排序

序言 你只管努力&#xff0c;其他交给时间&#xff0c;时间会证明一切。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用来标记二级论点 决定开一个算法专栏&#xff0c;希望能帮助大…

冒泡排序、插入排序、希尔排序、选择排序

一、排序协议的定义 在博客的开头的&#xff0c;我们先给出排序协议的定义。因为我们本篇博客含有多种排序方式&#xff0c;为了使每种排序方法对外调用方式一致&#xff0c;我们需要定义一个排序的相关协议。所有排序的相关类都必须遵循该协议&#xff0c;让此协议来定义具体…

Aiohttp异步爬取小说排行榜

Aiohttp异步爬取小说排行榜 *** Aiohttp简介及使用 *** ​ Aiohttp是Python的一个第三方网络编程模块&#xff0c; 它可以开发服务端和客户端&#xff0c;服务端也就是我们常说的网站服务器&#xff1b;客户端是访问网站的API接口&#xff0c;常用于接口测试&#xff0c;也可用…

Vue基础第七篇

一、vuex的使用 1.概念 在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xff0c;对vue应用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&#xff0c;且适用于任意组件间通信。 2.何时…

MyBatis操作数据库实现

说明&#xff1a;MyBatis是作用于三层架构开发&#xff0c;数据访问层&#xff08;Data Access Object&#xff09;的框架&#xff0c;用于访问数据库&#xff0c;对数据进行操作。 一、环境搭建 首先&#xff0c;创建一个SpringBoot模块&#xff0c;然后把MyBatis的环境搭建…

华为OD机试真题 JavaScript 实现【获取字符串中连续出现次数第k多的字母的次数】【2023Q1 100分】,附详细解题思路

一、题目描述 给定一个字符串&#xff0c;只包含大写字母&#xff0c;求在包含同一字母的子串中&#xff0c;长度第 k 长的子串的长度&#xff0c;相同字母只取最长的那个子串。 二、输入描述 第一行有一个子串(1<长度<100)&#xff0c;只包含大写字母&#xff1b;第二…

GEngine一个基于WebGPU的渲染引擎

一、废话篇&#xff1a; 2019年时候就有写一个渲染引擎想法&#xff0c;一直到现在才真正意义上算给实现了当初的想法&#xff0c;写了好几个月了和小伙伴这才有个初版&#xff08;虽然里面还有一堆bug哈&#xff0c;没时间改啊&#xff09;。说在前面GEngine借鉴了其他渲染引擎…

计算机网络方面的面试题目(合集)

python面试题 1、python下多线程的限制以及多进程中传递参数的方式 python多线程有个全局解释器锁(global interpreter lock)&#xff0c;这个锁的意思是任一时间只能有一个线程使用解释器&#xff0c;跟单cpu跑多个程序一个意思&#xff0c;大家都是轮着用的&#xff0c;这叫“…

在外web浏览器远程访问jupyter notebook服务器详细教程

文章目录 前言视频教程1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 前言 Jupyter Notebook&#xff0c;它是一个交互式的数据科学和计算环境&#xff0c;支持多种编程语言&#…

利用 canvas 实现背景图片和其他图片以及文字的组合生成新图片

预览世界效果图如下&#xff1a; 注&#xff1a;以下图片中&#xff0c;二维码部分是我动态生成的&#xff0c;以及姓名和工号位置的参数需要动态替换。 实现思路&#xff1a; 利用 canvas 实现在面板上画图以及绘制文字等等。 官方文档 API 地址如下&#xff1a;canvas AP…

知道效果广告,让你的广告投入更有价值!

效果广告作为一种能直接触达用户的广告&#xff0c;在互联网上遍地开花&#xff0c;今天我们就一起来了解下效果广告吧&#xff5e; 1.背景 在传统的门户广告、搜索广告中&#xff0c;一则广告的呈现是针对其所有可覆盖的受众&#xff0c;而真正对广告信息感兴趣的人群只是广大…

代码审计 底层逻辑

红队利用中&#xff0c;主要有以下几个板块。 找到漏洞-->利用漏洞-->权限维持-->痕迹清除。找到漏洞对应的技能是代码审计。 利用漏洞对应的技能是各和实战中利用技巧绕 waf。 权限维持&#xff0c;抽象来看&#xff0c;就是系统自己启动我的恶意代码&#xff0c;实现…

ROS学习——通信机制(话题通信③—注意事项)

2.1.2 话题通信基本操作A(C) Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 043话题通信(C)4_注意事项_Chapter2-ROS通信机制_哔哩哔哩_bilibili 1. int main(int argc, char const *argv[]){} vscode 中的 main 函数 声明 int main(int argc, char const *argv…

更新Navicat Premium 16.2 之 如何使用Navicat连接Redis的新手教程

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

向clickhouse插入一段由经纬度构成的路径

目录 背景粗暴简单字符串示例 数组套数组示例 LineStringWKT来帮忙参考资料 背景 现有一条路&#xff0c;这条路由好几段路段构成&#xff0c;每个路段又由一些轨迹点先后连接而成&#xff0c;且这些轨迹点数量不固定&#xff0c;有些路段由10个轨迹点连接而成&#xff0c;有些…

13 MCMC——马尔可夫链蒙特卡洛

文章目录 13 MCMC——马尔可夫链蒙特卡洛13.1 MCMC的意义13.2 简单采样方法介绍13.2.1 概率分布采样13.2.2 Rejection Sampling——拒绝采样13.2.3 Importance Sampling——重要性采样 13.3 Markov Chain知识补充13.3.1 Markov Chain定义13.3.2 Markov Chain性质——平稳分布13…

javaScript蓝桥杯----猜硬币

目录 一、介绍二、准备三、目标四、代码五、完成 一、介绍 为了打发无聊的时间&#xff0c;小蓝开发了一款人机对战的猜硬币游戏&#xff0c;页面中一共有 9 个杯子&#xff0c;系统会随机挑选 3 个杯子在里面放入硬币&#xff0c;玩家通过输入含有杯子序号的字符串进行猜选&a…

基于Python班级管理系统毕业设计-附源码171809

目 录 摘要 1 绪论 1.1研究背景 1.2研究的目的与意义 1.3系统开发技术的特色 1.4论文结构与章节安排 2 基于Python班级管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1数据增加流程 2.3.2数据修改流程 2.3.3数据删除流程 2.3 系统功能分析 2.3.1 功能性…

【考点】CKA 08_Kubernetes工作负载与调度 关系调度 nodeSelector 亲和性和反亲和性 污点 节点驱离与下线

文章目录 考试题目&#xff1a;deployment 扩容&#xff08;扩容命令&#xff09;1. Kubernetes 调度器1.1 调度概览1.2 kube-scheduler1.3 kube-scheduler 调度流程 2. Kubernetes 关系调度2.1 节点标签2.2 节点隔离/限制2.3 nodeName 字段2.3.1 准备工作2.3.2 创建使用 nodeN…

深度学习-第T10周——数据增强

深度学习-第T10周——数据增强 深度学习-第T10周——数据增强一、前言二、我的环境三、前期工作1、导入数据集2、查看图片数目 四、数据预处理1、 加载数据1.1、设置图片格式1.2、划分训练集1.3、划分验证集1.4、查看标签1.5、再次检查数据1.6、配置数据集 2、数据可视化 五、数…