C语言实现顺序栈以及栈的特点
什么是栈?
同顺序表和链表一样,栈也是用来存储逻辑关系为 “一对一” 数据的线性存储结构,如下图所示。
从上图我们看到,栈存储结构与之前所学的线性存储结构有所差异,这缘于栈对数据 “存” 和 “取” 的过程有特殊的要求:
- 栈只能从表的一端存取数据,另一端是封闭的,如上图所示;
- 在栈中,无论是存数据还是取数据,都必须遵循"先进后出"的原则,即最先进栈的元素最后出栈。拿上图的栈来说,从图中数据的存储状态可判断出,元素 1 是最先进的栈。因此,当需要从栈中取出元素 1 时,根据"先进后出"的原则,需提前将元素 3 和元素 2 从栈中取出,然后才能成功取出元素 1。
因此,我们可以给栈下一个定义,即栈是一种只能从表的一端存取数据且遵循 “先进后出” 原则的线性存储结构。
通常,栈的开口端被称为栈顶;相应地,封口端被称为栈底。因此,栈顶元素指的就是距离栈顶最近的元素,拿下图来说,栈顶元素为元素 4;同理,栈底元素指的是位于栈最底部的元素,下图中的栈底元素为元素。
进栈和出栈
基于栈结构的特点,在实际应用中,通常只会对栈执行以下两种操作:
- 向栈中添加元素,此过程被称为"进栈"(入栈或压栈);
- 从栈中提取出指定元素,此过程被称为"出栈"(或弹栈);
栈的具体实现
栈是一种 “特殊” 的线性存储结构,因此栈的具体实现有以下两种方式:
- 顺序栈:采用顺序存储结构可以模拟栈存储数据的特点,从而实现栈存储结构;
- 链栈:采用链式存储结构实现栈结构;
两种实现方式的区别,仅限于数据元素在实际物理空间上存放的相对位置,顺序栈底层采用的是数组,链栈底层采用的是链表。有关顺序栈和链栈的具体实现会在后续章节中作详细讲解。
顺序栈基本操作
顺序栈,即用顺序表实现栈存储结构。通过前面介绍我们知道,使用栈存储结构操作数据元素必须遵守 “先进后出” 的原则,下面就 “如何使用顺序表模拟栈以及实现对栈中数据的基本操作(出栈和入栈)” 给大家做一些介绍。
如果你仔细观察顺序表(底层实现是数组)和栈结构就会发现,它们存储数据的方式高度相似,只不过栈对数据的存取过程有特殊的限制,而顺序表没有。
例如,我们先使用顺序表(a 数组)存储{1,2,3,4}
,存储状态如下图所示:
同样,使用栈存储结构存储
{1,2,3,4}
,其存储状态如下图所示:通过上面两张图对比不难看出,使用顺序表模拟栈结构很简单,只需要将数据从 a 数组下标为 0 的位置依次存储即可。
从数组下标为 0 的模拟栈存储数据是常用的方法,从其他数组下标处存储数据也完全可以,这里只是为了方便初学者理解。
了解了顺序表模拟栈存储数据后,接下来看如何模拟栈中元素出栈的操作。由于栈对存储元素出栈的次序有"先进后出"的要求,如果想将图中存储的元素 1 从栈中取出,需先将元素 4、元素 3 和元素 2 依次从栈中取出。
这里给出使用顺序表模拟栈存储结构常用的实现思路,即在顺序表中设定一个实时指向栈顶元素的变量(一般命名为 top),top 初始值为 -1,表示栈中没有存储任何数据元素,及栈是"空栈"。一旦有数据元素进栈,则 top 就做 +1 操作;反之,如果数据元素出栈,top 就做 -1 操作。
顺序栈元素"入栈"
比如,还是模拟栈存储{1,2,3,4}
的过程。最初,栈是"空栈",即数组是空的,top 值为初始值 -1,如下图所示:
首先向栈中添加元素 1,我们默认数组下标为 0 一端表示栈底,因此,元素 1 被存储在数组 a[1] 处,同时 top 值 +1,如下图所示:
采用以上的方式,依次存储元素 2、3 和 4,最终,top 值变为 3,如下图所示:
因此,C 语言实现代码为:
//元素elem进栈,a为数组,top值为当前栈的栈顶位置
int push(int* a,int top,int elem){
a[++top]=elem;
return top;
}
代码中的 a[++top]=elem,等价于先执行 ++top,再执行 a[top]=elem。
顺序栈元素"出栈"
其实,top 变量的设置对模拟数据的 “入栈” 操作没有实际的帮助,它是为实现数据的 “出栈” 操作做准备的。
比如,将上图中的元素 2 出栈,则需要先将元素 4 和元素 3 依次出栈。需要注意的是,当有数据出栈时,要将 top 做 -1 操作。因此,元素 4 和元素 3 出栈的过程分别如下图a) 和 下图b) 所示:
注意,上图数组中元素的消失仅是为了方便初学者学习,其实,这里只需要对 top 值做 -1 操作即可,因为 top 值本身就表示栈的栈顶位置,因此 top-1 就等同于栈顶元素出栈。并且后期向栈中添加元素时,新元素会存储在类似元素 4 这样的旧元素位置上,将旧元素覆盖。
元素 4 和元素 3 全部出栈后,元素 2 才能出栈。因此,使用顺序表模拟数据出栈操作的 C 语言实现代码为:
//数据元素出栈
int pop(int * a,int top){
if (top==-1) {
printf("空栈");
return -1;
}
printf("弹栈元素:%d\n",a[top]);
top--;
return top;
}
代码中的 if 语句是为了防止用户做 “栈中已无数据却还要数据出栈” 的错误操作。代码中,关于对栈中元素出栈操作的实现,只需要 top 值 -1 即可。
以上就是本次给大家分享的利用C语言简单的实现顺序栈以及向大家介绍了栈的特点,完整的代码已经上传到github,C语言实现顺序栈 欢迎大家Star ! 想要了解其他相关数据结构算法实现的小伙伴也可以来我的博客MyBlog,我们一起交流,一起进步啊!
C语言实现顺序栈以及栈的特点的更多相关文章
- C语言实现顺序栈
C语言实现顺序栈,顺便加深刻++i,++i的区别 #include <stdio.h>#include <stdlib.h>#define maxsize 100/*写在前面的 ...
- C++语言实现顺序栈
C++语言实现顺序栈 在写C语言实现顺序栈的时候,我已经向大家介绍了栈的特点以及介绍了栈的相关操作,并利用C语言实现了相关算法.在这里小编就不在继续给大家介绍了,需要温习的可以去我的博客看看.在这篇博 ...
- 数据结构(C语言版)顺序栈相关算法的代码实现
这两天完成了栈的顺序存储结构的相关算法,包括初始化.压栈.出栈.取栈顶元素.判断栈是否为空.返回栈长度.栈的遍历.清栈.销毁栈.这次的实现过程有两点收获,总结如下: 一.清楚遍历栈的概念 栈的遍历指的 ...
- C语言实现顺序栈的初始化&进栈&出栈&读取栈顶元素
/*顺序表实现栈的一系列操作*/ #include<stdio.h> #include<stdlib.h> #define Stack_Size 50 //设栈中元素个数为50 ...
- C语言学习笔记——堆和栈——未整理
C语言笔记 栈区 栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出.出入栈是由C语言编译器自动分配 ...
- C语言函数调用时候内存中栈的动态变化详细分析(彩图)
版权声明:本文为博主原创文章,未经博主允许不得转载.欢迎联系我qq2488890051 https://blog.csdn.net/kangkanglhb88008/article/details/8 ...
- C语言中的堆与栈20160604
首先声明这里说的是C语言中的堆与栈,并不是数据结构中的!一.前言介绍:C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件是静态区域由代码段和数据段(由二部分部分组成:只读数据 段,未初始化数 ...
- 【转】C语言堆栈入门——堆和栈的区别
@2019-04-25 [小记] C语言堆栈入门——堆和栈的区别
- C语言数据结构基础学习笔记——栈和队列
之前我们学过了普通的线性表,接下来我们来了解一下两种特殊的线性表——栈和队列. 栈是只允许在一端进行插入或删除的线性表. 栈的顺序存储结构也叫作顺序栈,对于栈顶指针top,当栈为空栈时,top=-1: ...
随机推荐
- java -封装一个类。(姓名、年龄、性别)
//定义一个类. public class Maopao1{ //创建私有的对象. private String name; private int age; private String sex; ...
- 《Python学习手册 第五版》 -第18章 参数
在函数的定义和调用中,参数是使用最多喝最频繁的,本章内容就是围绕函数的参数进行讲解 本章重点内容如下: 1.参数的传递 1)不可变得参数传递 2)可变得参数传递 2.参数的匹配模式 1)位置次序:从左 ...
- 聊聊OkHttp实现WebSocket细节,包括鉴权和长连接保活及其原理!
一.序 OkHttp 应该算是 Android 中使用最广泛的网络库了,我们通常会利用它来实现 HTTP 请求,但是实际上它还可以支持 WebSocket,并且使用起来还非常的便捷. 那本文就来聊聊, ...
- hdu1226超级密码 bfs
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1226/ 题目大意是:寻找一个五百位之内的C进制密码,该密码是N的正整数倍,而且只能用给定的数构成密码,求这样的密 ...
- JavaScript----简介及基础语法
##JavaScript *概念:一门客户端脚本语言 *运行在客户端浏览器中的.每一个浏览器都有JavaScript的解析引擎. *脚本语言:不需要编译,直接就可以被浏览器解析执行. *功能: *可以 ...
- 【Unity游戏开发】跟着马三一起魔改LitJson
一.引子 在游戏开发中,我们少不了和数据打交道,数据的存储格式可谓是百花齐放,xml.json.csv.bin等等应有尽有.在这其中Json以其小巧轻便.可读性强.兼容性好等优点受到广大程序员的喜爱. ...
- vue2源码分析:patch函数
目录 1.patch函数的脉络 2.类vnode的设计 3.createPatch函数中的辅助函数和patch函数 4.源码运行展示(DEMO) 一.patch函数的脉络 首先梳理一下patch函数的 ...
- excel导出功能
/* * 导出 add by faby on 20180918 */ public void export(){ HttpServletResponse response=ServletAct ...
- mysql事务提交和回滚机制
应用场景: 银行取钱,从ATM机取钱,分为以下几个步骤 1 登陆ATM机,输入密码: 2 连接数据库,验证密码: 3 验证成功,获得用户信息,比如存款余额等: 4 用 ...
- 深度学习中正则化技术概述(附Python代码)
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 磐石 介绍 数据科学研究者们最常遇见的问题之一就是怎样避免过拟合. ...