【数据结构】线性表----栈详解

news2024/9/21 16:30:28

栈(Stack)是一种常见的数据结构,它具有**后进先出(Last In, First Out, LIFO)**的特点。栈的运作类似于物理世界中的叠盘子:最新放上去的盘子最先被拿走,而最底部的盘子最后才能被取出。

如果你先拿底下的盘子,那么就有可能出现整个盘子组全部倒塌碎落一地——这也就是所谓的栈出错。

出栈和入栈

栈有着先进后出的特点。所以它的出栈和入栈也遵循着这个特点。
我们在存取元素的时候,一般是在栈顶进行——也就是所谓的盘子顶;
而另一端称为栈底,一般就是数据结构的头结点。

入栈出栈的顺序只需记住:顺序必须有规律,例如

入栈:1234

出栈可以是:

1 432

234 1

但不能是:

3 1 4 2

在这里插入图片描述

栈的实现

栈既可以用数组也可以用链表形式实现,但由于栈本来就是连续的数据结构,所以使用数组刚好。如果非要使用链表,那么就使用单链表。(单链表可以解决的问题没必要使用双链表)

在这里插入图片描述

栈的基本操作

栈的主要操作包括:

  1. 入栈(Push): 将一个元素放入栈顶。
  2. 出栈(Pop): 移除并返回栈顶的元素。
  3. 查看栈顶元素(Peek/Top): 返回栈顶的元素但不移除它。
  4. 判断栈是否为空(IsEmpty): 检查栈中是否有元素。
  5. 获取栈的大小(Size): 返回栈中元素的数量。

接下来对其进行具体介绍和代码实现。

1.初始化和前期准备

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX 100  // 栈的最大容量,根据情况设置

typedef struct {
    int items[MAX];//容量
    int top;//栈顶元素
} Stack;

// 初始化栈
void initStack(Stack* s) {
    s->top = -1;栈顶指针指向-1的位置
}

// 检查栈是否为空
bool isEmpty(Stack* s) {
    return s->top == -1;
}

// 检查栈是否已满
bool isFull(Stack* s) {
    return s->top == MAX - 1;
}

2.入栈

// 入栈
void push(Stack* s, int item) {
    if (isFull(s)) {
        printf("Stack overflow\n");
        return;
    }
    s->items[++(s->top)] = item;
}

3.出栈

// 出栈
int pop(Stack* s) {
    if (isEmpty(s)) {
        printf("Stack underflow\n");
        exit(EXIT_FAILURE);
    }
    return s->items[(s->top)--];
}

在这里插入图片描述

4.删除和插入元素

// 删除栈中的元素(第n个位置)
void deleteElement(Stack* s, int position) {
    if (isEmpty(s) || position < 0 || position > s->top)//不在栈中无法进行删除 
    {
        printf("Invalid position\n");
        return;
    }

    for (int i = position; i < s->top; i++)//进行遍历寻找要删除的元素
    {
        s->items[i] = s->items[i + 1];
    }
    s->top--;
}

// 在栈中插入元素(第n个位置)
void insertElement(Stack* s, int position, int item) {
    if (isFull(s))//栈溢出
    {
        printf("Stack overflow\n");
        return;
    }
    if (position < 0 || position > s->top + 1) {
        printf("Invalid position\n");
        return;
    }

    for (int i = s->top; i >= position; i--) {
        s->items[i + 1] = s->items[i];
    }
    s->items[position] = item;
    s->top++;
}

栈的使用场景

栈在计算机科学和编程中有广泛的应用,如:

  • 函数调用管理: 编译器使用栈来管理函数调用和返回地址。
  • 表达式求值: 中缀表达式转换为后缀表达式,以及后缀表达式求值。
  • 撤销操作: 许多软件中的撤销(Undo)功能基于栈实现。

栈的注意事项

  1. 溢出问题: 在某些编程语言或环境中,栈的大小是有限的。如果不断入栈而不出栈,可能会导致栈溢出(Stack Overflow)。
  2. 访问限制: 栈只允许对栈顶进行操作,这意味着在栈中间的元素无法直接访问或修改。
  3. 异常处理: 在出栈或查看栈顶元素时,需要处理栈为空的情况,否则会引发错误。

另一种栈

实际上,以上都是栈在计算机科学以及数据结构中的解释,而在另一个计算机领域——计算机系统中,栈实际上是另一种事物。接下来对其进行简单的介绍。

在计算机系统中,栈(堆栈,Stack)是一种用于管理函数调用和局部变量的内存区域。它是计算机内存的一部分,负责存储函数调用过程中的临时数据,包括函数的参数、局部变量、返回地址等。

工作原理

  1. 栈帧(Stack Frame)

    • 每次函数调用时,都会在栈上分配一个新的栈帧。栈帧包含该函数的局部变量、参数和一些控制信息(如返回地址)。
    • 函数执行完毕后,其对应的栈帧会被弹出,返回控制权给调用它的函数。
  2. 入栈(Push)和出栈(Pop)

    • 入栈:当一个函数被调用时,相关数据(如参数和返回地址)会被推入栈中。
    • 出栈:当函数执行完毕后,其栈帧会被弹出,恢复之前的状态。
  3. 栈指针(Stack Pointer, SP)

    • 栈指针是一个寄存器,用于指向当前栈的顶端。每次入栈和出栈操作都会更新栈指针。
  4. 调用约定(Calling Convention)

    • 调用约定定义了函数如何传递参数、如何返回值以及如何维护堆栈。常见的调用约定有Cdecl、Stdcall、Fastcall等。

栈的用途

  1. 函数调用管理

    • 栈用于管理函数调用和返回,确保函数可以正确地调用其他函数,并在完成后返回调用点。
  2. 局部变量存储

    • 函数的局部变量通常存储在栈帧中,便于管理和清理。
  3. 递归支持

    • 栈结构天然支持递归调用,每次递归调用都会在栈上创建新的栈帧。

栈溢出(Stack Overflow)

栈的空间是有限的,如果函数调用层次过深(如递归调用过多),可能会导致栈空间耗尽,发生栈溢出。这种情况下,程序通常会崩溃或抛出异常。

这种栈的机制确保了函数调用的有序进行和局部变量的有效管理。

通过以上的介绍和代码示例,相信你对栈这种数据结构有了一个基本的了解。栈作为一种基础而重要的数据结构,我们会经常使用到它,所以需要熟练掌握。
ck Overflow)**

栈的空间是有限的,如果函数调用层次过深(如递归调用过多),可能会导致栈空间耗尽,发生栈溢出。这种情况下,程序通常会崩溃或抛出异常。

这种栈的机制确保了函数调用的有序进行和局部变量的有效管理。

通过以上的介绍和代码示例,相信你对栈这种数据结构有了一个基本的了解。栈作为一种基础而重要的数据结构,我们会经常使用到它,所以需要熟练掌握。

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

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

相关文章

C语言学习记录Day2

for循环 for&#xff08;表达式1&#xff1b;表达式2&#xff1b;表达式3&#xff09; 循环语句&#xff1b; 注&#xff1a;表达式1&#xff1a;初始化部分.表达式2&#xff1a;条件判断部分 表达式3&#xff1a;调整部分 不可再for循环体内修改循环变量&#xff0c;防止f…

【5G VoNR】VoNR流程简述

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G技术研究。 博客内容主要围绕…

支持向量机 (support vector machine,SVM)

支持向量机 &#xff08;support vector machine&#xff0c;SVM&#xff09; flyfish 支持向量机是一种用于分类和回归的机器学习模型。在分类任务中&#xff0c;SVM试图找到一个最佳的分隔超平面&#xff0c;使得不同类别的数据点在空间中被尽可能宽的间隔分开。 超平面方…

const 修饰不同内容区分

1.修饰局部变量 const int a 1;int const a 1; 这两种是一样的 注意&#xff1a; const int b; 该情况下编译器会报错&#xff1a;常量变量"b”需要初始值设定项 将一个变量没有赋初始值直接const修饰后&#xff0c;在以后时无法更改内容的。 2.修饰常量字符串 a.…

Python前沿技术:机器学习与人工智能

Python前沿技术&#xff1a;机器学习与人工智能 一、引言 随着科技的飞速发展&#xff0c;机器学习和人工智能&#xff08;AI&#xff09;已经成为了计算机科学领域的热门话题。Python作为一门易学易用且功能强大的编程语言&#xff0c;已经成为了这两个领域的首选语言之一。本…

U盘管理软件有哪些?3款好用的软件亲测有效!

在数字化办公与数据交换日益频繁的今天&#xff0c;U盘作为便携的存储设备&#xff0c;其重要性不言而喻。 然而&#xff0c;U盘的使用也带来了数据泄露、病毒感染等安全隐患。为了有效管理U盘&#xff0c;确保数据安全与合规性&#xff0c;市场上涌现出了众多U盘管理软件。 小…

电脑选购全解析!你需要知道的一切!

在选择电脑类型时&#xff0c;你可以考虑以下因素&#xff1a; 你的主要用途是什么&#xff1f; 你是否需要携带电脑&#xff1f; 你的预算是多少&#xff1f; 你对性能和图形要求有多高&#xff1f; 你是否需要特定的软硬件功能&#xff1f;根据这些因素&#xff0c;你可以…

生成式人工智能:开发者的得力助手还是职业威胁?

在过去的几年里&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;在软件开发领域引发了广泛关注。AI工具在代码生成、错误检测、自动化测试等方面的应用&#xff0c;正在迅速改变开发者的工作方式。AI究竟是在帮助开发者提高效率&#xff0c;还是在逐渐取代他们&#xf…

预提待摊费用处理费时费力?这样做更高效!

一笔费用发生之后&#xff0c;发票取得时间、资金支付时间、费用所属时间都可能不一致&#xff0c;在权责记账规则下&#xff0c;“预提”、“待摊”的账务处理方法成为企业财务业务处理的常用手段。相应地&#xff0c;预提和摊销业务在企业极为常见&#xff0c;仅针对企业规模…

Android network - NUD检测机制(Android 14)

Android network - NUD检测机制 1. 前言2. 源码分析2.1 ClientModeImpl2.2 IpClient2.3 IpReachabilityMonitor 1. 前言 在Android系统中&#xff0c;NUD&#xff08;Neighbor Unreachable Detection&#xff09;指的是网络中的邻居不可达检测机制&#xff0c;它用于检测设备是…

雅特力AT32F423开启FPU跟不开启FPU性能差异

在大多数Cortex-M的处理器中调试端口包含一个32位的自由运行计数器&#xff0c;它可以计算 CPU 的时钟周期。计数器是 Debug 观察和跟踪(DWT)模块的一部分&#xff0c;可以很容易地用于测量代码的执行时间。下面的代码是启用和初始化这个特性非常有用。 注意测试需要重新断电上…

浅谈信息技术高效课堂管理:策略、技巧与实践

引言&#xff1a; 在信息化教育的浪潮中&#xff0c;信息技术课程正逐渐成为学校教育体系中的重要组成部分。然而&#xff0c;信息技术课堂的特殊性——高互动性、高度依赖电子设备&#xff0c;给课堂管理带来了前所未有的挑战。如何在保证教学效率的同时&#xff0c;维护良好…

钡铼技术低成本解决方案:注塑机OPC UA接入的智慧选择

在工业4.0与“中国制造2025”战略的引领下&#xff0c;传统注塑机行业正面临前所未有的转型升级挑战。为了在这场技术革新浪潮中保持竞争力&#xff0c;积极接纳并实施OPC UA标准已成为必然趋势。那么&#xff0c;对于传统注塑机而言&#xff0c;如何平滑过渡实现对OPC UA的支持…

C++入门(C语言过渡)

文章目录 前言一、C关键字二、命名空间三、C输入&输出四、缺省参数五、函数重载六、引用七、inline八、nullptr总结 前言 C是一种通用的、高级的、静态类型的编程语言&#xff0c;它在20世纪80年代由丹尼斯里奇创建的C语言基础上发展而来。以下是C发展的一些重要里程碑。 1…

Linux 常见命令使用(超详细版)

文章目录 基本echo关机、重启命令上传下载工具rz/sz<、>、>>ls管道clearcdpwd 文件处理类命令mkdirrmdirtouchcpmv 文件查看类命令catmorelessheadtail 用户管理命令useraddpasswdusermoduserdelgroupaddgroupdel 文件属性类命令chmodchownchgrpln 文件压缩类命令t…

【免费数字孪生平台】零代码制作智慧农业蔬菜大棚可视化

一&#xff0e;智慧农业的价值 智慧农业&#xff0c;作为农业中的智慧经济形态&#xff0c;是现代科学技术与农业种植深度融合的产物。它通过将物联网、云计算、大数据、人工智能等现代信息技术集成应用于农业生产中&#xff0c;实现了农业生产的无人化、自动化和智能化管理。…

C语言下的文件详解

主要内容 文件概述文件指针文件的打开与关闭文件的读写 文件 把输入和输出的数据以文件的形式保存在计算机的外存储器上&#xff0c;可以确保数据能随时使用&#xff0c;避免反复输入和读取数据 文件概述 文件是指一组相关数据的有序集合 文件是存储数据的基本单位&#…

刘永先独家访谈:揭秘格行随身WiFi万店战略背后的“难而正确”之路

在随身WiFi市场鱼龙混杂、乱象频出的背景下&#xff0c;格行随身WiFi却毅然选择了一条少有人走的路——大规模布局线下门店。近日&#xff0c;每日财经新闻的记者有幸专访了格行随身WiFi的创始人刘永先&#xff0c;深入探讨了这一战略决策背后的考量与坚持。&#xff08;文章转…

DearLicy主题 | 小众化小清新风格的博客主题源码 | Typecho主题模版

DearLicy主题&#xff0c;一款小众化小清新风格的博客主题 主题支持Typecho所支持的所有版本PHP 简约、小众、优雅 安装教程 1.将主题上传至/usr/themes/文件夹下解压 2.后台进行启用 3.访问前台查看效果 图片&#xff1a;

Android Studio 的Gradle下载慢,Gradle切换下载源

看图 下面的文字地址因为转义符号的问题&#xff0c;https后面少了一个斜杠看图片进行补充&#xff0c;直接复制不知道能不能用 distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-8.7-bin.zip