【数据结构】C语言顺序栈和链式栈入栈和出栈操作

news2025/1/18 20:53:37

C语言顺序栈和链式栈入栈和出栈操作

    • 1、栈的基本概念
    • 2、栈的存储形式
    • 3、示例代码:
      • (1) 顺序栈:
      • (2) 顺序栈的应用:【十进制转二进制】
      • (3) 链式栈

1、栈的基本概念

栈是一种逻辑结构,是特殊的线性表。特殊在:

  • 只能在固定的一端操作

只要满足上述条件,那么这种特殊的线性表就会呈现一种“后进先出”的逻辑,这种逻辑就被称为栈。
由于约定了只能在线性表固定的一端进行操作,于是给栈这种特殊的线性表的“插入”、“删除”,另起了下面这些特定的名称:

  • 栈顶:可以进行插入删除的一端
  • 栈底:栈顶的对端
  • 入栈:将节点插入栈顶之上,也称为压栈,函数名通常为push()
  • 出栈:将节点从栈顶剔除,也称为弹栈(出栈),函数名通常为pop()
  • 取栈顶:取得栈顶元素,但不出栈,函数名通常为top()

2、栈的存储形式

栈只是一种数据逻辑,如何将数据存储于内存则是另一回事。一般而言,可以采用顺序存储形成顺序栈,或采用链式存储形成链式栈。

3、示例代码:

(1) 顺序栈:

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

#define STACK_SIZE  10

typedef struct stack
{
    // 真实存放数据的数组
    int data[STACK_SIZE];
    // 记录目前栈顶位置
    int top;
}sq_stack_t;

// 初始化顺序栈
sq_stack_t *sq_stack_init(void)
{
    sq_stack_t *my_sqstack = malloc(sizeof(sq_stack_t));
    // 给top赋初值
    my_sqstack->top = -1;
    return my_sqstack;
}

// 入栈
int push(int new_data, sq_stack_t *sq_stack)
{
    // 判断栈是否已满-栈未满
    if (sq_stack->top < STACK_SIZE - 1)
    {
        /* 更新top */
        sq_stack->top++;
        sq_stack->data[sq_stack->top] = new_data;
        return 0;
    }
    // 栈满了
    else
    {
        printf("栈已满!\n");
        return -1;
    }
}

// 出栈
int pop(sq_stack_t *sq_stack)
{
    // 判断栈是否空了
    if (sq_stack->top >= 0)
    {
        // 先保存栈顶元素
        int temp = sq_stack->data[sq_stack->top];
        // 清除原栈顶元素值
        sq_stack->data[sq_stack->top] = 0;
        // 更新栈顶 
        sq_stack->top--;
        return temp;
    }
    else
    {
        printf("栈已空!\n");
        return -1;
    }
}

int main(int argc, char const *argv[])
{
    /* 初始化顺序栈 */
    sq_stack_t *my_sqstack = sq_stack_init();
    // 入栈
    push(1, my_sqstack);
    push(2, my_sqstack);
    push(3, my_sqstack);
    push(4, my_sqstack);
    push(5, my_sqstack);

    // 出栈
    int size = my_sqstack->top;
    for(int i = 0; i <= size; i++)
    {
        printf("出栈的数据:%d\n", pop(my_sqstack));
    }
    return 0;
}

/*
执行结果:
    出栈的数据:5
    出栈的数据:4
    出栈的数据:3
    出栈的数据:2
    出栈的数据:1

*/ 

(2) 顺序栈的应用:【十进制转二进制】

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

#define STACK_SIZE  10

typedef struct stack
{
    // 真实存放数据的数组
    int data[STACK_SIZE];
    // 记录目前栈顶位置
    int top;
}sq_stack_t;

// 初始化顺序栈
sq_stack_t *sq_stack_init(void)
{
    sq_stack_t *my_sqstack = malloc(sizeof(sq_stack_t));
    // 给top赋初值
    my_sqstack->top = -1;
    return my_sqstack;
}

// 入栈
int push(int new_data, sq_stack_t *sq_stack)
{
    // 判断栈是否已满-栈未满
    if (sq_stack->top < STACK_SIZE - 1)
    {
        /* 更新top */
        sq_stack->top++;
        sq_stack->data[sq_stack->top] = new_data;
        return 0;
    }
    // 栈满了
    else
    {
        printf("栈已满!\n");
        return -1;
    }
}

// 出栈
int pop(sq_stack_t *sq_stack)
{
    // 判断栈是否空了
    if (sq_stack->top >= 0)
    {
        // 先保存栈顶元素
        int temp = sq_stack->data[sq_stack->top];
        // 清除原栈顶元素值
        sq_stack->data[sq_stack->top] = 0;
        // 更新栈顶 
        sq_stack->top--;
        return temp;
    }
    else
    {
        printf("栈已空!\n");
        return -1;
    }
}

/*
    实现将键盘输入的任意整数转换成2进制保存到栈里面,然后打印出来
*/
int main(int argc, char const *argv[])
{
    int num = 0;
    /* 初始化顺序栈 */
    sq_stack_t *my_sqstack = sq_stack_init();
    // 入栈
    printf("请输入任一整数:");
    scanf("%d", &num);
    while (num != 0)
    {
        push(num % 2, my_sqstack);
        num /= 2;
    }


    // 出栈
    int size = my_sqstack->top;
    for(int i = 0; i <= size; i++)
    {
        printf("出栈的数据:%d\n", pop(my_sqstack));
    }

    return 0;
}

/*
执行结果:
    请输入任一整数:15
    出栈的数据:1
    出栈的数据:1
    出栈的数据:1
    出栈的数据:1

*/ 

(3) 链式栈

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

typedef struct list_stack
{
    // 数据域
    int data;
    // 指针域
    struct list_stack *next;
    // 记录当前栈顶位置
    struct list_stack *top;

}list_stack_t;

// 初始化链式栈
list_stack_t *list_stack_init(void)
{
    // 申请堆空间
    list_stack_t *list_stack = malloc(sizeof(list_stack_t));
    
    list_stack->next = NULL;
    list_stack->top = NULL;

    return list_stack;
}
// 入栈
int push(int new_data, list_stack_t *list_stack)
{
    // 给新节点申请堆空间
    list_stack_t *new_node = malloc(sizeof(list_stack_t));
    if (new_node == NULL)
    {
        return -1;
    }
    new_node->data = new_data;
    new_node->next = NULL;
    new_node->top = NULL;

    list_stack_t *p = list_stack;
    while (p->next != NULL)
    {
        p = p->next;
    }
    p->next = new_node;

    // 更新栈顶位置
    list_stack->top = new_node;
    
    return 0;
}

// 出栈
int pop(list_stack_t *list_stack)
{
    // 判断栈是否空了
    if (list_stack->next == NULL)
    {
        printf("栈已空\n");
        return -1;
    }
    
    // 保存栈顶元素值
    int temp = list_stack->top->data;
    // 删除栈顶节点
    list_stack_t *p = list_stack;
    while (p->next->next != NULL)
    {
        p = p->next;
    }
    p->next = NULL;
    free(list_stack->top);
    // 更新栈顶位置
    list_stack->top = p;

    return temp;
}

int main(int argc, char const *argv[])
{
    unsigned char i;
    list_stack_t * my_list_stack = list_stack_init();
    for (i = 0; i < 5; i++)
    {
        push(i, my_list_stack);
    }
    for (i = 0; i < 9; i++)
    {
        printf("出栈数据:%d\n", pop(my_list_stack));
    }

    return 0;
}

/*
执行结果:
    出栈数据:4
    出栈数据:3
    出栈数据:2
    出栈数据:1
    出栈数据:0
    栈已空
    出栈数据:-1
    栈已空
    出栈数据:-1
    栈已空
    出栈数据:-1
    栈已空
    出栈数据:-1

*/

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

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

相关文章

SQL2000在win10上安装的方法

安装前最好先关闭防火墙和一些杀毒软件&#xff0c;因为这些软件在安装过程中可能会碰到注册表等一下杀毒软件比较敏感的地带&#xff0c;如果违反杀毒软件的规则会被当做病毒强行终止删除 首相找到C盘下window文件中的sysWOW64文件 鼠标右键&#xff0c;点击属性、安全、高级 …

【12】Word:张老师学术论文❗

目录 题目 ​NO2 NO3 NO4 NO5 NO6 NO7.8 题目 NO2 布局→页面设置→纸张&#xff1a;A4→页边距&#xff1a;上下左右边距→文档网格&#xff1a;只指定行网格→版式&#xff1a;页眉和页脚&#xff1a;页脚距边界&#xff1a;1.4cm居中设置论文页码&#xff1a;插入…

软件授权管理中的软件激活向导示例

软件激活向导示例 在软件许可中&#xff0c;提供许可应该是简单和安全的。这适用于想要在中央许可证服务器上创建新许可证的软件开发人员&#xff0c;也适用于需要在其设备上获得许可证的最终用户。如果所讨论的系统有互联网连接&#xff0c;或是暂时的连接&#xff0c;就可以…

基于微信小程序的摄影竞赛系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

在IDEA中使用通义灵码插件:全面提升开发效率的智能助手

在IDEA中使用通义灵码插件&#xff1a;全面提升开发效率的智能助手 随着软件开发行业对效率和质量要求的不断提高&#xff0c;开发者们一直在寻找能够简化工作流程、提升代码质量的工具。阿里云推出的通义灵码插件正是这样一个旨在帮助开发者更高效地编写高质量代码的强大工具…

【Unity3D】利用Hinge Joint 2D组件制作绳索效果

目录 一、动态绳索 &#xff08;可移动根节点&#xff09; 二、静态绳索 三、利用Skinning Editor(Unity2022.3.15f1正常使用) 四、注意事项 一、动态绳索 &#xff08;可移动根节点&#xff09; 动态绳索 DynamicRope空物体 Anchor和whitecircle是相同位置的物体&#xff…

游戏引擎学习第80天

Blackboard&#xff1a;增强碰撞循环&#xff0c;循环遍历两种类型的 t 值 计划对现有的碰撞检测循环进行修改&#xff0c;以便实现一些新的功能。具体来说&#xff0c;是希望处理在游戏中定义可行走区域和地面的一些实体。尽管这是一个2D游戏&#xff0c;目标是构建一些更丰富…

2025.1.15——四、布尔注入

题目来源&#xff1a;ctfhub技能树 目录 一、基本操作&#xff1a;整理已知信息&#xff0c;得到本题为布尔注入 方法一&#xff1a;手工盲注&#xff08;不推荐&#xff09; step 1&#xff1a;判断具体形式 step 2&#xff1a;查询字段数 step 3&#xff1a;通过回显判…

PE文件:节表-添加节

在所有节的空白区域都不够存放我们想要添加的数据时&#xff0c;这个时候可以通过添加节来扩展我们可操作的空间去存储新的数据&#xff08;如导入表、代码或资源&#xff09;。 过程步骤 1.判断是否有足够的空间添加节表 PE文件的节表紧跟在PE头之后&#xff0c;每个节表的…

【前端动效】HTML + CSS 实现打字机效果

目录 1. 效果展示 2. 思路分析 2.1 难点 2.2 实现思路 3. 代码实现 3.1 html部分 3.2 css部分 3.3 完整代码 4. 总结 1. 效果展示 如图所示&#xff0c;这次带来的是一个有趣的“擦除”效果&#xff0c;也可以叫做打字机效果&#xff0c;其中一段文本从左到右逐渐从…

Python基于Django的图像去雾算法研究和系统实现(附源码,文档说明)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

了解 BM25:一种高效的文本检索算法

什么是 BM25&#xff1f; BM25&#xff08;Best Matching 25&#xff09;是一种在信息检索领域非常著名的算法&#xff0c;它属于 TF-IDF 的改进版本&#xff0c;是许多现代搜索引擎和文本检索系统的核心算法之一。BM25 基于概率检索模型&#xff08;Probabilistic Informatio…

PenGymy论文阅读

这里发现idea被人家先发了&#xff0c;没办法&#xff0c;资料收集的不够全面&#xff0c;现在来学习一下这个项目 这篇论文的贡献如下&#xff1a; 总的来说&#xff0c;他的主要工作是构建逼真的仿真环境&#xff0c;然后根据这个仿真环境生成真实的靶场&#xff0c;使得这个…

猫贫血吃什么能快速补血?

各位铲屎官们&#xff0c;看到自家猫咪无精打采、小脸苍白&#xff0c;是不是特别心疼&#xff1f;贫血可是猫咪健康的大敌&#xff0c;今天就来给大家支支招&#xff0c;哪些食物和方法能让猫咪快速补血&#xff0c;恢复活力&#xff01; 一、红肉及内脏类 红肉是补血的“主力…

Redis 性能优化:多维度技术解析与实战策略

文章目录 1 基准性能2 使用 slowlog 优化耗时命令3 big key 优化4 使用 lazy free 特性5 缩短键值对的存储长度6 设置键值的过期时间7 禁用耗时长的查询命令8 使用 Pipeline 批量操作数据9 避免大量数据同时失效10 客户端使用优化11 限制 Redis 内存大小12 使用物理机而非虚拟机…

wireshark抓路由器上的包 抓包路由器数据

文字目录 抓包流程概述设置抓包配置选项 设置信道设置无线数据包加密信息设置MAC地址过滤器 抓取联网过程 抓包流程概述 使用Omnipeek软件分析网络数据包的流程大概可以分为以下几个步骤&#xff1a; 扫描路由器信息&#xff0c;确定抓包信道&#xff1b;设置连接路由器的…

在 Fluent 网格划分中使用薄网格特征

薄体模型的网格划分策略 薄体网格划分对于有效模拟薄壁结构或厚度明显小于其他尺寸的几何形状非常有利。当使用此类几何结构时&#xff0c;传统的体积网格划分技术可能会导致单元数量增加&#xff0c;因为它们试图捕获具有许多不必要单元的薄尺寸。薄体网格划分通过专门沿薄方…

大模型WebUI:Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(6)

大模型WebUI&#xff1a;Gradio全解11——Chatbot&#xff1a;融合大模型的多模态聊天机器人&#xff08;6&#xff09; 前言本篇摘要11. Chatbot&#xff1a;融合大模型的多模态聊天机器人11.6 为LLM Agent构建UI11.5.1 使用代理构建1. 使用transformers.agents的实际示例2. 使…

Linux-----线程同步(资源竞争和同步锁)

目录 资源竞争&#xff08;背景&#xff09; 锁&#xff08;解决方式&#xff0c;实现同步&#xff09; 互斥锁 读写锁 自旋锁 资源竞争&#xff08;背景&#xff09; 竞态条件 当多个线程并发访问和修改同一个共享资源&#xff08;如全局变量&#xff09;时&#xff0c;…

vue2 web 多标签输入框 elinput是否当前焦点

又来分享一点点工作积累及解决方案 产品中需要用户输入一些文字后按下回车键生成标签来显示在页面上&#xff0c;经过尝试与改造完成如下&#xff1a; <template><div class"tags-view" click"beginInput"><el-tag :key"index" …