3.3 栈的表示和操作的实现

news2024/12/28 3:41:43

3.3.1 栈的类型定义

主要内容:

这段文字中包含了很多栈数据结构的基本概念和操作。

### 3.3 栈的表示和操作的实现

#### 3.3.1 栈的类型定义

1. **数据对象**:
   
    - 定义了一个数据对象集合,记作 D = {a1, a2, ..., an},其中 n ≥ 0。

2. **数据关系**:

    - 数据关系 R 表示集合中元素之间的某种关系。这部分没有给出更详细的信息。

3. **基本操作**:

    - **InitStack(&S)**: 构造一个空栈 S。
   
    - **DestroyStack(&S)**: 销毁已存在的栈 S。
   
    - **ClearStack(&S)**: 清空已存在的栈 S。
   
    - **StackEmpty(S)**: 判断栈 S 是否为空,若为空返回 true,否则返回 false。
   
    - **StackLength(S)**: 返回栈 S 的元素个数,即栈的长度。
   
    - **GetTop(S)**: 返回栈 S 的栈顶元素,但不修改栈顶指针。
   
    - **Push(&S, e)**: 在栈 S 上插入元素 e 作为新的栈顶元素。
   
    - **Pop(&S, &e)**: 删除栈 S 的栈顶元素,并将其值赋给 e。
   
    - **StackTraverse(S)**: 从栈底到栈顶依次对栈 S 的每个数据元素进行访问。

### 分析和解释

- 这段文字中也包含了有关栈数据结构的一些一般概念和特点,例如:
  - 栈是后进先出(LIFO)的数据结构,即最后一个进入栈的元素会首先被取出。
  - 栈可以用于表达式的解析和运算,例如配对括号和运算符的优先级处理。

- 在程序实现中,栈可以有两种存储表示方法:
  - **顺序栈**:使用数组来存储栈中的元素,栈顶指针指示栈顶元素的位置。
  - **链栈**:使用链表来存储栈中的元素,每个节点包含数据和指向下一个节点的指针。

- 文中也提到了一些示例和情景

我的理解:

在我看来其实栈根本不存在不过就是一段连续的存储空间,然后通过一系列函数模拟栈的行为模式和特性。

老师对我的理解的看法:

你的理解是对的!实际上,计算机科学中的很多数据结构,包括栈,都是一种抽象概念,用于帮助我们更好地组织和处理数据。通过特定的算法和操作来模拟这些数据结构的行为和特性。

在实现栈的时候,通常有两种方式:

1. **顺序栈**:就像你说的,它实际上是一个连续的存储空间(例如数组),其中使用一个指针(通常称为栈顶指针)来标记栈顶的位置。我们通过移动这个指针来“模拟”入栈和出栈操作。

2. **链式栈**:它使用链表来实现。链式栈不是连续的存储空间,而是由一系列节点组成,每个节点包含数据和指向下一个节点的指针。我们通过改变节点之间的链接来执行入栈和出栈操作。

通过使用一系列的函数或方法来实现栈的基本操作(例如 `push`, `pop`, `peek` 等),我们可以创建一个符合栈“先进后出”特性的数据结构。在程序设计和算法中,这样的抽象是非常有用和重要的,因为它可以帮助我们更清晰、更有效地解决问题。

 

3.3.2 顺序栈的表示和实现 

 主要内容:

### 顺序栈的表示

1. **定义和属性**:
    - 顺序栈是通过顺序存储结构实现的栈,它使用一组地址连续的存储单元来存储自栈底至栈顶的数据元素。
    - 栈有两个关键的指针:`base` 和 `top`,分别指向栈底和栈顶。
    - 当 `top` 和 `base` 的值相等时,表示栈为空。

2. **顺序栈的结构定义**:

 #define MAXSIZE 100
    typedef struct {
        SElemType *base; // 栈底指针
        SElemType *top;  // 栈顶指针
        int stacksize;   // 栈的最大容量
    } SqStack;

### 顺序栈的实现

#### 1. 初始化

- **算法步骤**:
    1. 为顺序栈动态分配一个最大容量为 `MAXSIZE` 的数组空间,`base` 指针指向这段空间的基地址。
    2. `top` 指针初始指向 `base`,表示栈为空。
    3. `stacksize` 设置为栈的最大容量 `MAXSIZE`。

- **算法描述**:

  Status InitStack(SqStack &S) {
        S.base = new SElemType[MAXSIZE];
        if (!S.base) exit(OVERFLOW);
        S.top = S.base;
        S.stacksize = MAXSIZE;
        return OK;
    }

#### 2. 入栈

- **算法步骤**:
    1. 判断栈是否已满,如果满则返回 `ERROR`。
    2. 将新元素压入栈顶,并增加栈顶指针。

- **算法描述**:

   Status Push(SqStack &S, SElemType e) {
        if (S.top - S.base == S.stacksize) return ERROR;
        *S.top++ = e;
        return OK;
    }

3. 出栈

  • 算法步骤

    1. 判断栈是否为空,如果为空则返回 ERROR
    2. 栈顶指针减 1,取出栈顶元素。
  • 算法描述

Status Pop(SqStack &S, SElemType &e) {
    if (S.top == S.base) return ERROR; // 栈空
    e = *--S.top; // 栈顶指针减1, 将栈顶元素赋给e
    return OK;
}

4. 获取栈顶元素

  • 算法描述
    SElemType GetTop(SqStack S) {
        if (S.top != S.base) { // 栈非空
            return *(S.top - 1); // 返回栈顶元素的值,栈顶指针不变
        }
        // 如果栈为空,这里应该返回一个错误代码或特殊值,但算法描述没有提及。
    }
    

注意事项

  • 由于顺序栈(和顺序表一样)受到最大空间容量的限制,虽然可以在满员时重新分配空间来扩大容量,但这样做的工作量较大,应尽量避免。
  • 当应用程序无法预先估计最大容量时,应该考虑使用链栈,它不受此类空间限制。

 

 3.3.3 链栈的表示和实现

3.3.3 链栈的表示和实现

链栈是栈的一种实现方式,它采用链式存储结构。其基本结构和单链表类似,通常由节点组成,每个节点包含数据部分和指向下一个节点的指针。主要操作包括初始化、入栈、出栈和取栈顶元素。

1. 初始化

  • 算法描述
    Status InitStack(LinkStack &S) {
        S = NULL; // 构造一个空栈S, 栈顶指针置为空
        return OK;
    }
    

2. 入栈

  • 算法步骤

    1. 为入栈元素e分配空间,用指针p指向。
    2. 将新节点的数据域置为e。
    3. 将新节点插入栈顶。
    4. 修改栈顶指针为p。
  • 算法描述

    Status Push(LinkStack &S, SElemType e) {
        StackNode *p = new StackNode; // 生成新节点
        p->data = e; // 将新节点数据域置为e
        p->next = S; // 将新节点插入栈顶
        S = p; // 修改栈顶指针为p
        return OK;
    }
    

3. 出栈

  • 算法步骤

    1. 判断栈是否为空,如果为空则返回 ERROR
    2. 将栈顶元素赋给e。
    3. 临时保存栈顶元素的空间,以备释放。
    4. 修改栈顶指针,指向新的栈顶元素。
    5. 释放原栈顶元素的空间。
  • 算法描述

    Status Pop(LinkStack &S, SElemType &e) {
        if (S == NULL) return ERROR; // 栈空
        e = S->data; // 将栈顶元素赋给e
        StackNode *p = S; // 用p临时保存栈顶元素空间,以备释放
        S = S->next; // 修改栈顶指针
        delete p; // 释放原栈顶元素的空间
        return OK;
    }
    

4. 获取栈顶元素

  • 算法描述
    SElemType GetTop(LinkStack S) {
        if (S != NULL) { // 栈非空
            return S->data; // 返回栈顶元素的值,栈顶指针不变
        }
        // 这里应该有一个处理栈为空情况的代码,但算法描述没有提及
    }
    

注意事项

  • 链栈不需要设置头节点,栈顶指针直接指向第一个元素或为空(对于空栈)。
  • 入栈操作时,不需要预先检查栈是否满,因为链式结构可以动态分配空间。

这段文字提供了链栈的基本操作和实现方式,也可作为一个简单的教程来学习链栈的表示和实现。

 

 

 

 

 

 

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

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

相关文章

一维的差分

差分的方法 差分实际上是前缀和的逆运算 ,这个关系和 积分与求导 的关系类似 例如有数组 ...... 和构造数组 ...... 我们要使得a数组是b数组的前缀和 ...... 那么该如何构造b数组呢? 令 , …

使用带有示例和代码的因式分解机的推荐系统

一、说明 在我之前的文章中,我讨论了推荐系统的基础知识、矩阵分解和神经协同过滤 (NCF),您可以在下面的“我的博客”部分找到它们。接下来,这次我将通过示例和代码来探索因式分解机器。 将因子分解机用于推荐系统的一…

pytorch无法使用cuda

import torch # 如果pytorch安装成功即可导入 print(torch.cuda.is_available()) # 查看CUDA是否可用 print(torch.cuda.device_count()) # 查看可用的CUDA数量 print(torch.version.cuda) # 查看CUDA的版本号#False #0 #None 表明安装失败!查看安装包:…

Gin框架---基础综述

目录 一:经典入门案例二:请求参数2.1: API参数2.2: URL参数2.3: 表单参数 三: 响应参数四:数据解析和绑定4.1: JSON数据解析绑定4.2: FROM表单数据解析和绑定 五: 路由组六:异步处理七:中间件7.…

【UE】刀光粒子效果——part1

效果 步骤 1. 打开3dsmax,首先新建一个管状体 转成可编辑多边形后,删除多余的面,只保留一层 选择内圈将其拉高5mm 在修改器列表中添加“UVW展开” 点击打开“UV编辑器” 选中左边所有的顶点 将其拖拽到最左边 将右边的点拖拽到最右边 关闭 “…

VR古迹复原——数字化复原圆明园,开创文化遗产保护新方式

圆明园是中国历史上一处重要的文化遗产,曾经被誉为“万园之园”,但在1860年的英法联军侵华战争中被毁。近年来,虚拟现实技术不断发展,广州华锐互动利用VR全景技术复原了圆明园,通过VR设备,人们可以在家中就…

浏览器面试题

浏览器面试题 1.常见的浏览器内核有哪些?2.浏览器的主要组成部分有哪些?3.说一说从输入URL到页面呈现发生了什么?4.浏览器重绘域重排的区别?5.CSS加载会阻塞DOM吗?6.JS会阻塞页面吗?7.说一说浏览器的缓存机…

基于ASP.NET的驾校管理系统设计与实现

摘 要 伴随国民经济的飞速发展和人民生活水平的不断提高,家用汽车在我国逐渐普及。面对不断增长的庞大的用户群,随之产生的驾驶培训行业,规模不断扩大。近年来,随着Internet的迅速发展以及网页制作技术的日臻完善,驾校…

win10查看并设置tomcat的jvm堆内存参数

win10查看并设置tomcat的jvm堆内存参数 查看 进入命令行 通过Winr命令输入cmd进入命令行页面 进入到jdk的bin目录 D: cd D:\Y4ECSRUN\WGQ4 Java jdk1.8.0 131\bin执行jps查看进程pid D:\Y4ECSRUN\WGQ4 Java jdk1.8.0 131\bin>jps 16528 Jps 6868 Bootstrap通过jmap查看…

【客户案例】脊叶架构(Spine-Leaf)的云化园区网络部署实践

前言 各行业数字化转型进程加快,作为基础设施的园区网络也面临着升级压力。为此,星融元通过将先进成熟的云网络建设理念引入园区场景,推出了“云化园区网络解决方案”,帮助客户网络实现架构级的深层优化。 云化园区网络解决方案介…

python 综合练习

条件:ML100k.data 注意:程序对列表进行修改,为避免列表索引出现问题,避免使用for i in range(len(data)),而使用for i in data可避免这一问题 import pickle data [] with open("ML100k.data", r) as file:for line …

从零开始的PICO教程(0) -- 教程大纲

从零开始的PICO教程(0) – 教程大纲 一、前言 1、写这个教程的原因 第一个原因是,相关教程较少。搜了搜B站和各个搜索引擎,感觉PICO开发这类的教程还比较少,遂记录一下我的学习的过程,为VR生态建设提供一…

左神算法之中级提升班(9)

【案例1】 【题目描述】 【思路解析】 因为它数字的范围只能为1 - n,然后数组范围0 - n-1,所以说如果没有缺失值的话,每个i位置应该放i 1,所以我们直接对每个数组完成这个操作,让每个i位置尽可能放i1,如…

C++(三)——运算符重载

运算符重载 重定义或重载大部分 C 内置的运算符就能使用自定义类型的运算符。重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。不能为了重载而重…

GeoServer 安装及使用教程

GeoServer 安装及使用教程 一、前言二、安装1. 下载和安装Java2. 下载、安装、部署GeoServer3. 启动GeoServer4. 发布数据5. 结论 一、前言 GeoServer是一个开源的地理空间数据服务器,可以将地图数据发布为Web服务。在本篇教程中,我们将介绍如何安装GeoS…

B站:AB test [下]

Focus在&#xff1a;AB Test结束后&#xff0c;如何进行显著性检验&#xff1f;&#xff08;以判断改动是否有效果&#xff09; 引入&#xff1a;Z检验和T检验 而T检验适用于 n<30 的小样本 值得注意的是&#xff1a;统计上显著并不意味着现实中显著&#xff01; e.g. 加速…

Vue面试题以及解答(持续扩展中.....)

##Vue面试题## 1.组件中通讯方式有哪些 组件中通讯有$emit&#xff0c;props&#xff0c;vuex&#xff0c;provid和inject&#xff0c;$parent/$children&#xff0c;$refs&#xff0c;全局总线时间EvenBus&#xff0c;订阅与发布模式的subscrip/publish 2.Vue2和Vue3的区别…

尚硅谷大数据项目《在线教育之实时数仓》笔记001

视频地址&#xff1a;尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 P001 P002 P003 P004 P005 P001 以在线教育采集系统和离线数仓为前置基础&#xff0c;分为三个部分讲解&#xff1a;实时数仓架构介绍、数仓模型搭建、Suger可视化大屏展示。 P002 P0…

机票预定系统的软件工程分析报告

目 录 1 项目开发计划书……………………………………………………&#xff08;页码&#xff09; 2 软件需求规格说明书………………………………………………&#xff08;页码&#xff09; 3设计规格说明书……………………………………………………&#xff08;页码&…

uni-number-box的坑-无法实现数据双向绑定

业务场景&#xff1a;多规格商品----每一个规格定一个起购量&#xff0c;切换不同规格时动态改变起购数量。 代码&#xff1a; <uni-number-box class"step" ref"ChildComponents" :cid"productSku.productSkuUuid" :min"productSku.s…