数据结构:栈(C语言实现)
栈的定义
栈是一种特殊的线性表,它的逻辑结构和线性表相同,只是运算规则与线性表相比有了更多的限制,其实之后会接触的一种数据结构——队列也是特殊的线性表,但队列不在本篇讨论的范围了。栈与队列都可以称作运算受限的线性表
具体来讲它的定义,栈是限制在表的一端进行插入和删除的线性表。允许插入、删除的这一端称为栈顶,而距离栈顶最远的(即另一个固定端)称为栈底,当表中没有元素时成为空栈。因为只能在一端插入或删除,所以我们可以说栈是按“后进先出”的规则进行操作,称为后进先出的线性表,简称LIFO表。栈的插入操作我们称为进栈,又叫做入栈;栈的删除操作我们称为出栈,又叫做弹栈。
如上图,栈像极了一个容器,我们可以往里面放东西,而要拿东西出来的时候,我们只能拿位于容器上面的东西。那按照这种说法,是不是最先进栈的元素一定最后一个出栈呢?答案是非也。
我们举个例子,现有三个元素1、2、3,要将这三个元素依次进栈,出栈的顺序有几种呢。
- 1、2、3依次进栈,出栈的顺序就是3、2、1。
- 1进,2进,2出,1出,3进,3出,出栈的顺序是2、1、3。
- 1进,1出,2进,3进,3出,2出,出栈的顺序是1、3、2。
- 1进,2进,2出,3进,3出,1出,出栈的顺序是2、1、3。
- 1进,1出,2进,2出,3进,3出,出栈的顺序是1、2、3。
上述情况可知,元素出栈的形式是多变的。
栈的基本操作
我们在上面说过:栈是一种特殊的线性表,那么也和线性表一样分为两类:顺序栈、链栈(下图)。
定义
顺序栈我们可以用数组来表示,通常来说,0 下标端设为栈底,并且用一个栈顶指针top来表示,比如当栈内有 5 个元素,那么栈顶元素的下标就是 4,即 top = 4 ,由此推出,若栈此时为空栈时,栈顶指针 top = -1 ,入栈时,栈顶指针加 1。
// define Status
typedef enum Status {ERROR = 0, SUCCESS = 1
} Status;// define element type
typedef int ElemType;// define struct of stack
typedef struct SqStack {ElemType *elem;int top;int size; //定义栈的大小
} SqStack;
链栈和链表就差不多了,与顺序栈相比,同样是需要一个栈顶指针指向栈顶,进栈和出栈采用类似链表中的插入、删除接口来完成,值得注意的是,栈的主要运算是在栈顶插入、删除,显然在链表的头部作栈顶最方便(插入采用前插法)。
// define Status
typedef enum Status {ERROR = 0, SUCCESS = 1
} Status;// define element type
typedef int ElemType;// define struct of stack
typedef struct StackNode
{ElemType data;struct StackNode *next;
}StackNode, *LinkStackPtr;//define pointer of stack
typedef struct LinkStack{LinkStackPtr top;int count;
}LinkStack;
初始化
链栈中我们为 s->top 申请了内存空间,而这个空间是指针的空间,不是栈的空间, s->top 只是一个指针,s-> top->next才是 s->top指针所指的栈顶元素。
//基于数组的顺序栈
Status initStack(SqStack *s,int sizes)
{s->elem = (ElemType*)malloc(sizes * sizeof(ElemType));if (!s->elem)return ERROR;s->top = -1;s->size = sizes;return SUCCESS;
}//基于链表的链栈
Status initLStack(LinkStack *s)
{s->top = (LinkStackPtr)malloc(sizeof(StackNode));if (!s->top)return ERROR;s->count = 0;return SUCCESS;
}
判断栈是否为空
这个接口其实特别简单,要判断栈是否为空,顺序栈就是看 s->top 是不是等于 -1;链栈就是看 s->count 是不是等于 0(也可以看 s->top->next 是否为NULL)
//基于数组的顺序栈
Status isEmptyStack(SqStack *s)
{return s->top == -1;
}//基于链表的链栈
Status isEmptyLStack(LinkStack *s)
{return s->count == 0;
}
读栈顶元素
当然是要瞧瞧栈顶指针指的那个位置啦
//基于数组的顺序栈
Status getTopStack(SqStack *s,ElemType *e)
{if (s->top == -1)return ERROR;*e = s->elem[s->top];return SUCCESS;
}//基于链表的链栈
tatus getTopLStack(LinkStack *s,ElemType *e)
{if(s->count == 0 || !s->top)return ERROR;*e = s->top->next->data;return SUCCESS;
}
清空
这里的清空并不是销毁,清空只是把所有元素出栈而已,栈还是可以继续使用的。
//基于数组的顺序栈
Status clearStack(SqStack *s)
{if (!s)return ERROR;s->top = -1;return SUCCESS;
}//基于链表的链栈
Status clearLStack(LinkStack *s)
{LinkStackPtr ptem, p = s->top->next; //p指向栈顶元素if (!s->top)return ERROR;while (p){ //这里也可以循环调用出栈接口ptem = p->next;free(p); //free栈顶元素p = ptem;}s->count = 0; //计数器归零return SUCCESS;
}
销毁
要把我们申请的内存空间全部free
//基于数组的顺序栈
Status destroyStack(SqStack *s)
{if (!s)return ERROR;free(s->elem);return SUCCESS;
}//基于链表的链栈
Status destroyLStack(LinkStack *s)
{LinkStackPtr ptem, p = s->top->next;if (!s->top)return ERROR;while (s->count != 0){ //这里也可以调用清空接口ptem = p->next;free(p);s->top->next = ptem;s->count--;}free(s->top);return SUCCESS;
}
栈长
栈的长度直接看 s->top 和 s->count 的值就可以啦
//基于数组的顺序栈
Status stackLength(SqStack *s,int *length)
{if (!s)return ERROR;*length = s->top + 1;return SUCCESS;
}//基于链表的链栈
Status LStackLength(LinkStack *s,int *length)
{if (!s->top)return ERROR;*length = s->count;return SUCCESS;
}
进栈
因为顺序栈需要我们事先定义栈的大小,所以在进栈操作前,要先判断栈是否已满;而链栈在某个层面上说是没有大小限制的,可以随便进栈,除非内存满了。
//基于数组的顺序栈
Status pushStack(SqStack *s,ElemType data)
{if (!s || s->top == s->size - 1) //判断栈是否已满return ERROR;s->top++;s->elem[s->top] = data;return SUCCESS;
}//基于链表的链栈
Status pushLStack(LinkStack *s,ElemType data)
{StackNode *p;if(!s->top)return ERROR;p = (StackNode*)malloc(sizeof(StackNode));p->data = data;p->next = s->top->next;s->top->next = p;s->count++;return SUCCESS;
}
出栈
出栈也要判断一下栈是否已空
//基于数组的顺序栈
Status popStack(SqStack *s)
{if (!s || s->top == -1) //这里也可以调用 “判断栈是否为空” 接口return ERROR;s->top--;return SUCCESS;
}//基于链表的链栈
Status popLStack(LinkStack *s, ElemType *data)
{LinkStackPtr ptem, p = s->top->next;if(!s->top || s->count == 0) //这里也可以调用 “判断栈是否为空” 接口return ERROR;*data = p->data; //出栈的元素存储到 dataptem = p->next;free(p);s->top->next = ptem;s->count--;return SUCCESS;
}
参考:
算法与数据结构(C语言版) 主编·邓玉洁
数据结构:栈(C语言实现)相关推荐
- 表达式求值(数据结构栈,c语言版)
表达式求值 一.实验题目 1.案例分析 2.案例实现 3.算法步骤 4.算法描述 二.工具环境 三.实验问题 四.实验代码 一.实验题目 1.案例分析 任何一个表达式都是由操作数(operand)运算 ...
- 数据结构——栈(C语言)
C语言实现栈 github代码下载 一. 栈的概念及结构 二.栈的实现 2.1 栈的存储定义 2.2 栈的初始化 2.3 入栈 2.4 出栈 2.5 获取栈顶元素 2.6 获取栈中有效元素个数 2.7 ...
- 数据结构-栈(C语言代码)
栈(stack)又名堆栈,它是一种运算受限的线性表.限定仅在表尾进行插入和删除操作的线性表.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元素放到栈顶元 ...
- c语言 栈结构存放数据类型,数据结构——栈的详解
栈和队列是两种重要的线性结构,从数据结构的角度看,栈和队列也是线性表,其特殊性在于栈和队列的基本操作是线性表的子集.他们是操作受限的线性表,因此,可称为限定性的数据结构.但从数据类型角度看,他们是和线 ...
- 数据结构(C语言版) 第 三 章 栈与队列 知识梳理 + 作业习题详解
目录 一.栈 0.栈的基本概念 1.栈的实现 2.栈与递归 3.Hanoi塔问题 二.队列 0.队列的基本概念 1.队列的实现 2.循环队列 2.1循环队列的相关条件和公式: 3.链队列 4.链队列完 ...
- java语言链栈_Java语言实现数据结构栈代码详解
近来复习数据结构,自己动手实现了栈.栈是一种限制插入和删除只能在一个位置上的表.最基本的操作是进栈和出栈,因此,又被叫作"先进后出"表. 首先了解下栈的概念: 栈是限定仅在表头进行 ...
- 11.0、C语言数据结构——栈
11.0.C语言数据结构--栈 栈的定义: 栈是一种重要的线性结构,可以这样讲,栈是前面讲过的线性表的一种具体形式: 官方定义:栈(stack)是一个 后进先出(Las ...
- c语言特殊计算器设计报告,C语言数据结构栈计算器的实现课题设计报告书
C语言数据结构栈计算器的实现课题设计报告书 (13页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 目录1. 课程设计任务 12. 需求分析 ...
- 资料分享:送你一本《数据结构(C语言版)》电子书!
要想写出可复用.可扩展.易维护.灵活性好的代码,「数据结构」这一关必须要过啊! 在数据结构与算法的众多教材中,奉为经典的当属清华大学严蔚敏老师的著作.很多学校也选择这本书作为考研指定教材. 正在学习数 ...
- 资料分享:送你一本《数据结构(C#语言版)》电子书!
对于信息类专业的学生而言,数据结构与算法是一门必修的课程.只有学好这门课程,熟练掌握线性表.栈.队列.树.图等基本结构,以及在这些结构上的各种算法,才能利用计算机去解决实际问题. 如何学好这门课程呢, ...
最新文章
- SQL Server各种日期计算方法
- 《从零构建前后分离web项目》:开篇 - 纵观WEB历史演变
- 数据结构 - 二叉排序树
- C#链接数据库增删改查的例子
- Hive动态分区 参数配置及语法
- vmware虚拟机中ubuntu上网问题
- 《阿里巴巴中国总裁叶朋:B2B从1.0向2.0的升级》阅读整理
- 在ASP.NET AJAX中使用应用程序服务和本地化(5):自定义应用程序服务的服务器端实现...
- DOM.getBoundingClientRect()
- appscan如何进行web端安全性测试_如何进行WEB安全性测试?
- Atitit.现在的常用gui技术与gui技术趋势评价总结
- 防范非法用户入侵系统秘籍
- 云计算平台能够提供计算服务器,云计算平台提供了什么服务器
- PSP游戏下载地址大全
- stm32+TB6612驱动直流电机
- 无法处理文件 Snoop\Forms\BindingMap.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记。要想处理这些文件,请删除 Web 标记。
- 读博太孤独?你不是一个人!
- caj文献里的参考文献拷贝到word中格式错乱问题
- Python 十进制到六进制
- 百度地图API学习---隐藏百度版权标志
热门文章
- mc方块云服务器地址,我的世界方块大陆服务器地址ip-城镇|开荒|纯净|生存(我的世界1.14.4版本)...
- 希沃展台如何使用_简单又实用的希沃视频展台
- c语言csae中没有break,条件语句2
- McAfee迈克菲安全软件的垃圾性以及win10的脆弱性
- 黑马程序员 一步一步往上爬 学习毕老师java视频的第03,04天
- 阿里云智能客服系统:包括智能导航、客服助手、智能外呼、呼叫中心、在线客服、智能培训等。经阿里内部多年实际使用演变而来,功能齐全,产品化程度高,可本地化部署。有需要的可以联系我。
- 输入框回车多个文本_CAD制图初学入门:回车键和空格键在CAD软件中的作用
- 中国信通院发布《数据中心白皮书(2022年)》
- 2022-2028年中国航空轮胎行业市场发展潜力及投资风险预测报告
- 提高英语听力最好的学习方法