数据结构之栈

2023-11-13

  • 什么是栈?
    1.后进者先出,先进者后出,这就是典型的“栈”结构
    2.从栈的操作特性来看,是一种“操作受限”的线性表,只允许在端插入和删除数据

  • 为什么需要栈?
    1.栈是一种操作受限的数据结构,其操作特性用数组和链表均可实现
    2.但,任何数据结构都是对特定应用场景的抽象,数组和链表虽然使用起来更加灵活,但却暴露了几乎所有的操作,难免会引起错误操作的风险。
    3.所以,当某个数据集合只涉及在某端插入和删除数据,且满足后进者先出,先进者后出的操作特性时,我们应该首选栈这种数据结构

核心代码:

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

//    定义一个节点的结构
typedef struct node
{
    int member;            //数据域
    struct node * pNext;//指针域
}Node,*pNode;

//    定义一个栈结构
typedef struct stack
{
    pNode Top;            //栈顶
    pNode Bottom;        //栈底
}Stack,* pStack;

void InitStack(pStack );        //    初始化栈的函数
bool Push(pStack ,int);            //    进行压栈操作的函数
void TraverseStack(pStack );    //    遍历栈函数
bool Empty(pStack );            //    判断栈是否为空的函数
int Pop(pStack );                //    进行出栈操作的函数
void Clear(pStack );            //    清空栈的函数

int main(void)
{
    Stack s;                        //    定义一个栈
    int i;
    int num;
    int data;                        //    临时保存用户输入的数据
    int re_num;                        //    保存Pop函数的返回值
    InitStack(&s);
    printf("你想输入几个数据啊:");
    scanf("%d",&num);
    for (i = 0;i < num;i++)
    {
        printf("第 %d 个数:",i+1);
        scanf("%d",&data);
        if (Push(&s,data))                //    调用Push函数
        {
            continue;
        }
        else
        {
            printf("进行进栈操作失败!\n");
            exit(-1);
        }
    }
    TraverseStack(&s);                //    调用遍历函数
    printf("你想去掉几个数啊: ");
    scanf("%d",&data);
    printf("你去掉的数字是:");
    for (i = 0; i < data;i++)
    {
        re_num = Pop(&s);            //    调用Pop函数,并把返回值赋给re_num;
        printf("%d ",re_num);
    }
    printf("看看删除后还有啥:");
    TraverseStack(&s);
    printf("\n");
    Clear(&s);                        //    调用清空栈函数
    printf("遍历下看看栈清空没····\n");
    TraverseStack(&s);
    printf("\n");
    return 0;
}

//    进行栈的初始化的函数
void InitStack(pStack ps)
{
    ps->Top = (pNode)malloc(sizeof(Node));        //    分配内存空间给栈顶
    if (NULL == ps->Top)
    {
        printf("动态分配内存失败\n");
        exit(-1);
    }
    else
    {
        ps->Bottom = ps->Top;                    //    使栈底也指向栈顶空间
        ps->Top->pNext = NULL;                    //    栈顶指针置为NULL;
    }
    return ;
}

//    进行进栈操作的函数
bool Push(pStack ps,int data)
{
    pNode pNew = (pNode)malloc(sizeof(Node));    //    定义一个新节点,并分配内存空间
    if (NULL == pNew)
    {
        return false;
    }
    pNew->member = data;                        //    把要进栈的数据赋给新节点的member成员
    pNew->pNext = ps->Top;                        //    使新节点的指针指向栈顶
    ps->Top = pNew;                                //    把新节点作为新栈顶

    return true;
}

//    遍历栈的函数
void TraverseStack(pStack ps)
{
    pNode pNew = ps->Top;
    while(pNew!= ps->Bottom)                //    只要栈顶不等于栈底,循环
    {
        printf("%d ",pNew->member);            //    打印栈顶的成员member
        pNew = pNew->pNext;                //    栈顶指针向下移动一次
    }
    return ;
}

//    判断栈是否为空
bool Empty(pStack ps)
{
    if(ps->Top == ps->Bottom)    //    栈顶等于栈底,不就是栈中没数据么
    {
        return true;
    }
    else
    {
        return false;
    }
}

//    进行出栈操作函数
int Pop(pStack ps)
{
    pNode pSwap = NULL;            
    int return_val;
    if (Empty(ps))                //判断栈是否为空,为空就不能进行出栈操作
    {
        exit(-1);
    }
    else
    {
        return_val = ps->Top->member;    //    把栈顶的成员member的值赋给return_val做为函数返回值
        pSwap = ps->Top;                //    使pSwap指向栈顶
        ps->Top = ps->Top->pNext;        //    使栈顶指向栈顶下一个节点
        free(pSwap);                    //    释放以前的栈顶空间
        return return_val;
    }
}

//    清空栈的函数
void Clear(pStack ps)
{
    pNode pNew = NULL;
    
    while (ps->Top != ps->Bottom)        //    栈顶和栈底不等,循环
    {
        pNew = ps->Top;                    //    使一个新节点和栈顶指向同一空间
        ps->Top = ps->Top->pNext;        //    使栈顶指向栈顶的下一个节点
        free(pNew);                        //    释放掉以前的栈顶空间
    }
    return ;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构之栈 的相关文章

  • Ubuntu 下安装 OpenSSH Server

    Ubuntu 下安装 OpenSSH Server 是无比轻松的一件事情 需要的命令只有一条 sudo apt get install openssh server 查看返回的结果 如果没有出错 则用putty SecureCRT SSH

随机推荐

  • Deprecated usages detected, please refer to the el-pagination documentation for more details

    遇到这个问题 说明你用el pagination分页器参数传递不正确 在这里插入图片描述 https img blog csdnimg cn 5952bad428654dda8d956181f45183d5 png 我的是由于total没有
  • 在tinymce富文本中插入本地视频解决方案

    前言 最近在改一个别人的项目时候 遇到一个需求 要在tinymce富文本中添加本地视频 tinymce富文本本身是不具备添加本地视频的功能的 需要使用一些其他手段来添加本地视频 小demo截图 方法 1 在富文本的外面写一个添加视频的按钮
  • 第二十九章 Unity关节Joint

    关节组件将刚体连接到另一个刚体或空间中的固定点 关节施加使刚体移动的力 而关节限制功能可以限制该移动 Unity 提供的以下关节可以对刚体组件施加不同的力和限制 从而使这些刚体具有不同的运动 Hinge Joint铰链关节 使两个刚体像被连
  • 软件工程——结构化设计

    一 结构化软件设计的任务 在结构化设计方法中 概要设计阶段将软件需求转化为数据结构和软件的系统结构 概要设计阶段要完成体系结构设计 数据设计及接口设计 详细设计阶段要完成过程设计 二 结构化设计与结构化分析的关系 结构化设计方法的实施要点
  • android 旋转屏幕导致Activity重建解决方法

    横竖屏切换时候activity的生命周期 1 不设置Activity的android configChanges时 切屏会重新调用各个生命周期 切横屏时会执行一次 切竖屏时会执行两次 2 设置Activity的android configC
  • python 根据当前时间创建文件

    在当前目录中批量创建文件 文件名为 Y m d H M S格式的当前时间 精确到秒 为防止出现重名文件 在每创建一个文件后 让线程休眠一秒 import time def create global name localTime time
  • vue-router 源码:前端路由

    前言 在学习 vue router 的代码之前 先来简单了解一下前端路由 前端路由主要有两种实现方法 Hash 路由 History 路由 先来看看这两种方法的实现原理 接着我们将用它们来简单实现一个自己的前端路由 前端路由 Hash 路由
  • 开关电源电感电压波形过冲和下冲原理以及处理办法

    以一个同步降压电路例子来讲解 测量电感左端的电压波形如图所示 很明显可以看到电压尖刺 那么为什么会产生这个尖刺 从电路原理中我们知道 实际上电路是有很多寄生参数的 从图中可以知道实际电路可以等效一个RCL电路 过冲和下冲原理是一样的 这里以
  • Linux带宽限速———针对网卡与进程操作限速

    使用 Wondershaper 限制网络带宽 yum y install wondershaper Wondershaper 可以用于限制特定网络接口 如 eth0 wlan0 的下载和上传速度 使用 Wondershaper 来限制接口的
  • 概要设计的必要性及写法

    1 1 文档的重要性 很多小伙伴在需求 开发 测试阶段不注重文档 认为这耽误时间 画蛇添足 实际上文档对于软件行业是十分重要的 软件的定义 软件是包括程序 数据及其相关文档的完整集合 从这个定义中我们能够体会到文档的重要性 很多小伙伴常说要
  • 物联网智能家居系统

    源码部分可以找我我给你的哦 l3O6l4O8O52 扣扣 物联网智能家居系统 18年07 19 实训项目 1 需求分析 原理 基础准备 1 1实验目的 1 2基本功能 1 3模块功能描述 1 3 1主功能函数模块 1 3 2串口通信模块 1
  • gensim.models.word2vec 参数说明

    使用gensim训练词向量的实例 Initialize and train a Word2Vec model gt gt gt from gensim models import Word2Vec gt gt gt sentences ca
  • Es、kibana安装教程-ES(二)

    上篇文章介绍了ES负责数据存储 计算和搜索 他与传统数据库不同 是基于倒排索引来解决问题的 Kibana是es可视化工具 分布式搜索ElasticSearch ES 一 一 ElasticSearch安装 官网下载地址 https www
  • VS Code自动补全生成代码免费插件BitoAI使用指南2023

    2023年是AI爆发元年 已经被各种AI工具 新闻轰炸了几个月 只有一种感觉 时间不够用 本文介绍编程辅助神器 Bito AI Bito是什么 Bito是一款插件 它目前支持VS Code Chrome插件 以及Jetbrains的全系列I
  • Linux安装镜像仓库Harbor

    先来看一下Harbor的页面 不管是页面布局 还是操作功能 明显比registry好 1 安装docker docker安装 2 安装docker compse Harbor对docker compse的版本是有要求的 我记得是要高于1 1
  • 去银行写代码是种什么体验?

    本文转载自程序员技术 一线互联网岗位和银行 国企还是有点区别的 这篇文章 讲详细讲一讲银行或者金融科技的相关问题 包括面试 待遇等等 虽然前阵子网传几大互联网公司都去掉了大小周 但是我和某团的一个哥们儿聊 其实本质是把周末要加的班 放在了平
  • 登录Unity官方商店时提示Sorry, this link is no longer valid.(此链接已失效)

    看了看网上的资料 主要有以下四种方法 第一种非常有效 1 彻底断开当前使用的wifi或者有线网络 打开手机热点 让电脑连接热点 重新登录 就可以进去了 2 关闭魔法 3 打开系统防火墙 设置Unity相关程序为允许专用网络和允许公用网络 都
  • 哨兵-1 Sentinel-1数据下载(欧空局)

    Sentinel 1数据下载 1 Sentinel 1 数据简介 2 Sentinel 1 数据下载步骤 2 1 在欧空局 ESA 下载Sentinel 1 数据 2 1 1网站页面介绍 2 1 2 数据下载步骤 1 Sentinel 1
  • Python pyinstaller打包opencv程序出错(ImportError: OpenCV loader: missing configuration file: [‘config.py‘)

    在打包含有opencv库的程序时 打包 F w 后运行程序报错 运行失败 查看命令行提示 打包时只 F 错误为 ImportError OpenCV loader missing configuration file config py C
  • 数据结构之栈

    栈 什么是栈 1 后进者先出 先进者后出 这就是典型的 栈 结构 2 从栈的操作特性来看 是一种 操作受限 的线性表 只允许在端插入和删除数据 为什么需要栈 1 栈是一种操作受限的数据结构 其操作特性用数组和链表均可实现 2 但 任何数据结