数据结构_day3

目录

4.栈 stack

4.2.1 特性

练习:

4.3 链式栈

4.3.1 特性

总结:


4.栈 stack

4.2.1 特性

逻辑结构:线性结构

存储结构:顺序结构

操作:创建、入栈、出栈、判空和判满

创空:

入栈:

出栈:

代码实现:

#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct seqstack
{
    int maxlen;     //表示数组元素总个数
    datatype *data; //指向存放数据的数组的指针
    int top;        //栈顶有可以称栈针,本质还是最后一个有效元素下标等同于之前学的顺序表的last
} seqstack_t;

//创建空顺序栈, len代表创建栈时的最大长度
seqstack_t *createEmptySeqStack(int len)
{
    //1. 开辟顺序栈结构体大小空间
    seqstack_t *p = (seqstack_t *)malloc(sizeof(seqstack_t));
    if (NULL == p)
    {
        perror("p malloc err");
        return NULL;
    }
    //2. 初始化结构体空间
    p->top = -1;                                          //如同之前的last初始化为-1,因为元素个数是0,下标是0-1=-1
    p->maxlen = len;                                      //保存数组长度可以通过传参获取
    p->data = (datatype *)malloc(sizeof(datatype) * len); //开辟数组大小空间,单个元素大小乘以元素个数
    if (NULL == p->data)
    {
        perror("p->data malloc err");
        return NULL;
    }

    return p;
}

//判断是否为满,满返回1 未满返回0
int isFullSeqStack(seqstack_t *p)
{
    return p->top + 1 == p->maxlen;
}

//入栈,data代表入栈的数据
int pushStack(seqstack_t *p, int data)
{
    //  1. 判满: p->top + 1 == p->maxlen
    if (isFullSeqStack(p))
    {
        printf("pushStack err\n");
        return -1;
    }
    // 让top栈顶加一
    p->top++;
    // 将数据入栈
    p->data[p->top] = data;

    return 0;
}

//判断栈是否为空
int isEmptySeqStack(seqstack_t *p)
{
    return p->top == -1;
}

//出栈
int popSeqStack(seqstack_t *p)
{
    //1.容错判断
    if (isEmptySeqStack(p))
    {
        printf("popSeqStack\n");
        return -1;
    }
    //printf("%d\n", p->data[p->top]);  //或者加打印也可以
    //2. 将栈针top减一
    p->top--;
    //3. 返回要出栈数据
    return p->data[p->top + 1];
}

int main(int argc, char const *argv[])
{
    seqstack_t *p = createEmptySeqStack(6);
    for (int i = 0; i < 7; i++)
        pushStack(p, i); //最后报一个pushStack err,因为栈满了

    while (!isEmptySeqStack(p))
        printf("%d\n", popSeqStack(p));  //5 4 3 2 1 0 后进先出
    return 0;
}

练习:

*通动力校园招聘笔试题

1. 若进栈顺序为 1,2,3,4 一下四种情况不可能出现的出栈序列是( )

  A.  1,4,3,2    //入1出1入234出4出3出2

  B.  2,3,4,1    //入12 出2 入3 出3 入4出4 出1

  C.  3,1,4,2

  D.  3,4,2,1 //入123出3入4出4出2 出1

  1. 下列叙述正确的是( )

A. 线性表是线性结构

B. 栈与队列是非线性结构

C. 线性链表是非线性结构

  1. 二叉树是线性结构

3. 下列关于栈叙述正确的是( )

    A.在栈中只能插入数据

    B.在栈中只能删除数据

    C.栈是先进先出的线性表

    D.栈是先进后出的线性表

4.请问下面的程序有问题吗?如果有问题在哪儿?

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

void get_mem(int *q) //q=NULL
{
    q = (int *)malloc(sizeof(int)); //改变q不会影响到函数外的p, 开辟空间也不够
}

int main(int argc, char const *argv[])
{

    int i;
    int *p = NULL;
    get_mem(p); //函数调用完成后p还是等于NULL
    for (i = 0; i < 10; i++)
        p[i] = i;

    for (i = 0; i < 10; i++)
        printf("%d\n", p[i]);

    free(p);

    return 0;
}
​​​​​​​​​​​​​​

错误:相当于值传递,改变函数内的q不会影响到主函数的p,函数调用后p还是等于NULL。再一个开辟空间大小不够,只开辟了4字节。

修改:可以通过传递二级指针,或者返回值

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

void get_mem(int **q) //q=&p
{
    *q = (int *)malloc(sizeof(int) * 10); //*q = *&p =p ,也就是操作*q就等同操作函数外的p
}

int main(int argc, char const *argv[])
{
    int i;
    int *p = NULL;
    get_mem(&p); //函数调用结束后p真的指向了堆区
    for (i = 0; i < 10; i++)
        p[i] = i;

    for (i = 0; i < 10; i++)
        printf("%d\n", p[i]);

    free(p);

    return 0;
}

4.3 链式栈

4.3.1 特性

逻辑结构:线性结构

存储结构:链式存储

顺序栈和链式栈的区别:存储结构不同,实现的方式也不同,顺序栈是用顺序表实现而链式栈用链表实现。

栈的操作:创建、入栈、出栈、判空

入栈:

出栈:

代码实现:

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

typedef int datatype;
typedef struct node
{
    datatype data;
    struct node *next;
} node_t, *node_p;

//创建一个空栈
void createEmptyLinkStack(node_p *p) //p=&top
{
    *p = NULL; //*p = top = NULL
}

//入栈, data是入栈的数据
int pushLinkStack(node_p *p, datatype data) //因为要用p接收函数外的&top来在函数内找到top, 所以参数需要为二级指针。
{
    // 创建新节点
    node_p pnew = (node_p)malloc(sizeof(node_t));
    if (NULL == pnew)
    {
        perror("pnew malloc err");
        return -1;
    }
    // 将要入栈数据存入新节点
    pnew->data = data;
    pnew->next = NULL;
    // 将新节点连入到链表中
    pnew->next = *p; //*p=top
    // 移动栈针到新的栈顶节点
    *p = pnew;
    return 0;
}

//判断栈是否为空
int isEmptyLinkStack(node_p p)
{
    return p == NULL;
}

//出栈
datatype popLinkStack(node_p *p) //p=&top
{
    node_p pdel = NULL;
    //1. 判空:*p == NULL;
    if (isEmptyLinkStack(*p)) //*p=top
    {
        printf("popLinkStack err\n");
        return -1;
    }
    //2. 让指针pdel指向栈顶节点
    pdel = *p;
    //3. 移动栈针到下一个节点
    *p = (*p)->next; //*p=pdel->next;
    //4. 定义临时变量保存要出栈数据: temp = pdel->data;
    datatype temp = pdel->data;
    //5. 释放要被删除节点: free(pdel);
    free(pdel);
    //6. 返回要出栈数据:return temp;
    return temp;
}

//求栈的长度
int lengthLinkStack(node_p p) //传递一级指针,因为不需要移动栈针(也就是主函数的top)。
{
    int len = 0;
    while (p != NULL)
    {
        len++;
        p = p->next;
    }
    return len;
}

int main(int argc, char const *argv[])
{
    node_p top;
    createEmptyLinkStack(&top); //top=NULL
    pushLinkStack(&top, 1);
    pushLinkStack(&top, 2);
    pushLinkStack(&top, 3);

    printf("len=%d\n", lengthLinkStack(top));

    while (!isEmptyLinkStack(top))
    {
        printf("%d\n", popLinkStack(&top)); //3 2 1
    }

    return 0;
}

总结:

顺序栈和链式栈的区别是什么?

  1. 顺序栈是顺序存储,内存连续,用顺序表实现;链表是链式存储,内存不连续,用链表实现。
  2. 顺序栈的长度固定,而链栈不会。​​​​​​​

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【自然语言处理】多头注意力机制 Multi-Head Attention

多头注意力&#xff08;Multi-Head Attention&#xff09;机制是Transformer模型中的一个关键组件&#xff0c;广泛用于自然语言处理任务&#xff08;如机器翻译、文本生成等&#xff09;以及图像处理任务。它的核心思想是通过多个不同的注意力头来捕获输入的不同特征&#xff…

虚拟现实与Facebook的结合:未来社交的全新体验

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术正在逐步改变人们的社交方式。Facebook&#xff0c;作为全球最大的社交媒体平台之一&#xff0c;积极探索如何将虚拟现实融入其社交生态系统&#xff0c;创造全新的用户体验。这一结合不仅影响了用户之间…

深度解析机器学习的四大核心功能:分类、回归、聚类与降维

深度解析机器学习的四大核心功能&#xff1a;分类、回归、聚类与降维 前言分类&#xff08;Classification&#xff09;&#xff1a;预测离散标签的艺术关键算法与代码示例逻辑回归支持向量机&#xff08;SVM&#xff09; 回归&#xff08;Regression&#xff09;&#xff1a;预…

探索秘境:如何使用智能体插件打造专属的小众旅游助手『小众旅游探险家』

文章目录 摘要引言智能体介绍和亮点展示介绍亮点展示 已发布智能体运行效果智能体创意想法创意想法创意实现路径拆解 如何制作智能体可能会遇到的几个问题快速调优指南总结未来展望 摘要 本文将详细介绍如何使用智能体平台开发一款名为“小众旅游探险家”的旅游智能体。通过这…

获取非加密邮件协议中的用户名和密码——安全风险演示

引言 在当今的数字时代,网络安全变得越来越重要。本文将演示如何通过抓包工具获取非加密邮件协议中的用户名和密码,以此说明使用非加密协议的潜在安全风险。通过这个演示,我们希望能提高读者的安全意识,促使大家采取更安全的通信方式。 注意: 本文仅用于教育目的,旨在提高安全…

【MyBatis】初识MyBatis 构建简单框架

目录 MyBatis前言搭建一个简单的MyBatis创建Maven项目引入必要依赖创建数据表结构创建User实体类创建Mapper接口Mapper层Dao层 创建MyBatis的Mapper映射文件编写测试类传统测试类JUnit测试 MyBatis 介绍&#xff1a;MyBatis是一款半自动的ORM持久层框架&#xff0c;具有较高的…

Linux下ClamAV源代码安装与使用说明

Linux下ClamAV源代码安装与使用说明 ClamAV(Clam AntiVirus)是一款开源的防病毒工具,广泛应用于Linux平台上的网络安全领域。它以其高效的性能和灵活的配置选项,成为网络安全从业人员的重要工具。ClamAV支持多线程扫描,可以自动升级病毒库,并且支持多个操作系统,包括Li…

NGINX 保护 Web 应用安全之基于 IP 地址的访问

根据客户端的 IP 地址控制访问 使用 HTTP 或 stream 访问模块控制对受保护资源的访问&#xff1a; location /admin/ { deny 10.0.0.1; allow 10.0.0.0/20; allow 2001:0db8::/32; deny all; } } 给定的 location 代码块允许来自 10.0.0.0/20 中的任何 IPv4 地址访问&#xf…

可视化大屏中运用3D模型,能够带来什么好处。

现在你看到的可视化大屏&#xff0c;大都会在中间放置一些3D模型&#xff0c;比如厂房、园区、设备等等&#xff0c;那么这些3D模型的放置的确给可视化大屏带来了不一样的视觉冲击&#xff0c;本文将从以下四个方面来分析这个现象。 一、可视化大屏中越来越多使用3D模型说明了…

Linux工具的使用-【git的理解和使用】【调试器gdb的使用】

目录 Linux工具的使用-031.git1.1git是什么1.2git在linux下的操作1.2.1创建git仓库1.2.2 .gitignore1.2.3 .git&#xff08;本地仓库&#xff09;1.2.4 add (添加)1.2.5 commit(提交)1.2.6push(推送)对两个特殊情况的处理配置免密码push 1.2.7 log(获取提交记录)1.2.8 status(获…

Java项目-基于springboot框架的逍遥大药房管理系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

Linux运维篇-误操作已经做了pv的磁盘导致pv异常

目录 故障场景排错过程小结 故障场景 在对/dev/vdb1创建了pv并扩容至vg(klas)之后&#xff0c;不小心对/dev/vdb进行了parted操作&#xff0c;删除了/dev/vdb1导致pvs查看显示异常。具体过程如下所示&#xff1a; 正常创建pv 将创建好的pv添加到系统现有的卷组中 不小心又对…

Golang | Leetcode Golang题解之第491题非递减子序列

题目&#xff1a; 题解&#xff1a; var (temp []intans [][]int )func findSubsequences(nums []int) [][]int {ans [][]int{}dfs(0, math.MinInt32, nums)return ans }func dfs(cur, last int, nums []int) {if cur len(nums) {if len(temp) > 2 {t : make([]int, len(…

【计网】理解TCP全连接队列与tcpdump抓包

希望是火&#xff0c;失望是烟&#xff0c; 生活就是一边点火&#xff0c;一边冒烟。 理解TCP全连接队列与tcpdump抓包 1 TCP 全连接队列1.1 重谈listen函数1.2 初步理解全连接队列1.3 深入理解全连接队列 2 tcpdump抓包 1 TCP 全连接队列 1.1 重谈listen函数 这里我们使用…

颜色交替的最短路径

题目链接 颜色交替的最短路径 题目描述 注意 返回长度为n的数组answer&#xff0c;其中answer[x]是从节点0到节点x的红色边和蓝色边交替出现的最短路径的长度图中每条边为红色或者蓝色&#xff0c;且可能存在自环或平行边 解答思路 可以使用广度优先遍历从0开始找到其相邻…

Java.6--多态-设计模式-抽象父类-抽象方法

一、多态 1.定义--什么是多态&#xff1f; a.同一个父类的不同子类对象&#xff0c;在做同一行为的时候&#xff0c;有不同的表现形式&#xff0c;这就是多态。&#xff08;总结为&#xff1a;一个父类下的不同子类&#xff0c;同一行为&#xff0c;不同表现形式。&#xff0…

leetcode day1 910+16

910 最小差值 给你一个整数数组 nums&#xff0c;和一个整数 k 。 在一个操作中&#xff0c;您可以选择 0 < i < nums.length 的任何索引 i 。将 nums[i] 改为 nums[i] x &#xff0c;其中 x 是一个范围为 [-k, k] 的任意整数。对于每个索引 i &#xff0c;最多 只能 …

Excel中如何进行傅里叶变换(FT),几步完成

在 Excel 中&#xff0c;虽然没有像 MATLAB 那样专门的函数库来直接进行傅里叶变换&#xff0c;但可以使用 Excel 内置的分析工具库提供的傅里叶变换&#xff08;FT &#xff0c;Fourier Transform&#xff09;功能。这个工具可以对数据进行频域分析。以下是如何在 Excel 中进行…

开源表单生成器OpnForm

什么是 OpnForm &#xff1f; OpnForm 是一个开源的表单构建工具&#xff0c;旨在简化创建自定义表单的过程&#xff0c;特别适合无编码知识的用户。它通过人工智能优化表单创建流程&#xff0c;支持多种用途&#xff0c;如联系人表单、调查表等。OpnForm 提供了一个直观的拖放…