数据结构学习笔记——链式存储结构实现栈(链栈)
目录
- 一、链栈的定义
- 二、链栈的初始化
- 三、判断链栈是否为空栈
- 四、进栈(插入操作)
- 五、出栈(删除操作)
- 六、读取链栈的栈顶元素
- 七、链栈的建立
- 八、链栈的遍历输出
- 链式存储结构实现栈完整代码
- 一个简单的链栈的基本实现例子
一、链栈的定义
- 有两种方式实现栈,分别是顺序存储结构和链式存储结构,这里我们把通过
链式存储结构
实现的栈成为链栈
,链栈相对于顺序栈其最大优势是可以动态地分配存储空间
,所以通常不会出现栈满的情况,这里我们通过不带头结点的单链表实现链栈(是因为栈的主要操作都是在栈顶进行操作的),即第一个结点设为栈顶从而方便操作。
如下图,也就是一个不带头结点的单链表,即不带头结点的链栈,其中Lhead指针指向栈中的栈顶元素:
链栈的类型定义代码如下:
#include<stdio.h>
#include<stdlib.h>typedef struct StackNode {int data;//存放栈中元素struct StackNode *Lhead;//栈顶指针 ,记录栈顶元素的位置
} *LinkStack;//链栈的类型定义
二、链栈的初始化
初始化一个空栈,将链栈类型的变量S标识为空,即S=NULL
,如下代码:
/*链栈的初始化,初始化一个空栈*/
bool InitStack(LinkStack &S) {S=NULL;return true;
}
三、判断链栈是否为空栈
当链栈S为空时表示为空栈,否则不为空,通过if条件语句判断,即S==NULL
,如下代码:
/*判断链栈是否为空*/
bool EmptyStack(LinkStack S){if(S==NULL)return true;elsereturn false;
}
四、进栈(插入操作)
同单链表当中动态分配新结点的步骤类似,创建一个值为x的新结点p(通过malloc()函数动态分配,需在开头加头文件#include<stdlib.h>),首先将x值赋给新结点p的数据域中,然后将新结点p插入到链栈的栈顶前,最后再将新结点p作为当前栈顶元素,完整代码如下:
/*进栈(插入操作)*/
void PushStack(LinkStack &S, int x) {StackNode *p;p = (StackNode*)malloc(sizeof(StackNode));//动态分配创建一个新结点pp->data = x; //将x放入新结点p的数据域中p->Lhead = S; //将新结点p插入到当前链栈的栈顶前S = p; //将新结点p作为栈顶元素
}
五、出栈(删除操作)
出栈操作首先必须判断栈是否为空
,即S==NULL,然后通过变量x,将栈顶元素S->data赋给x取出,然后将指针p指向原栈顶(为要删除的结点),并将栈顶S指向下一个结点,最后通过free()函数释放要删除的结点p,完整代码如下:
/*出栈(删除操作)*/
bool PopStack(LinkStack &S,int &x) {StackNode *p;if(S==NULL)//若栈为空,则报错return false;x=S->data;//x记录当前栈顶元素p=S;//p指针指向原栈顶S=S->Lhead;//S指向下一个结点free(p);//释放栈顶元素return true;
}
六、读取链栈的栈顶元素
通过变量x使其存储栈顶结点,即S->data,读取链栈的栈顶元素的代码如下:
/*读取链栈的栈顶元素*/
bool GetTopStack(LinkStack &S,int &x) {if(S==NULL)return false;x=S->data;return true;
}
七、链栈的建立
链栈的建立通过输入要建立的栈的元素个数来一键建立链栈,每次输入入栈的元素,然后通过PushStack()函数使其入栈,代码如下:
/*链栈的建立*/
void CreateStack(LinkStack &S,int x) {int number;printf("请输入要建立的栈中的元素个数:\n");scanf("%d",&number);for(int i=0; i<number; i++) {printf("输入第%d个入栈的元素:\n",i+1);scanf("%d",&x);PushStack(S,x);}
}
八、链栈的遍历输出
链栈的遍历输出也就是遍历链栈,使p指针等于S,然后每次指向下一个结点,同时输入此时指针p指向结点的值p->data,代码如下:
/*链栈的遍历输出*/
bool PrintStack(LinkStack S) {StackNode *p=S;if(p==NULL)return false;while(p!=NULL) {printf("%d ",p->data);p=p->Lhead;}
}
链式存储结构实现栈完整代码
链式存储结构实现栈的完整代码如下:
#include<stdio.h>
#include<stdlib.h>typedef struct StackNode {int data;//存放栈中元素struct StackNode *Lhead;//栈顶指针 ,记录栈顶元素的位置
} *LinkStack;//链栈的类型定义/*链栈的初始化,初始化一个空栈*/
bool InitStack(LinkStack &S) {S=NULL;return true;
}/*判断链栈是否为空*/
bool EmptyStack(LinkStack S) {if(S==NULL)return true;elsereturn false;
}/*进栈(插入操作)*/
void PushStack(LinkStack &S, int x) {StackNode *p;p = (StackNode*)malloc(sizeof(StackNode));//动态分配创建一个新结点pp->data = x; //将x放入新结点p的数据域中p->Lhead = S; //将新结点p插入到当前链栈的栈顶前S = p; //将新结点p作为栈顶元素
}/*出栈(删除操作)*/
bool PopStack(LinkStack &S,int &x) {StackNode *p;if(S==NULL)//若栈为空,则报错return false;x=S->data;//x记录当前栈顶元素p=S;//p指针指向原栈顶S=S->Lhead;//S指向下一个结点free(p);//释放栈顶元素return true;
}/*读取链栈的栈顶元素*/
bool GetTopStack(LinkStack &S,int &x) {if(S==NULL)return false;x=S->data;return true;
}/*链栈的建立*/
void CreateStack(LinkStack &S,int x) {int number;printf("请输入要建立的栈中的元素个数:\n");scanf("%d",&number);for(int i=0; i<number; i++) {printf("输入第%d个入栈的元素:\n",i+1);scanf("%d",&x);PushStack(S,x);}
}/*链栈的遍历输出*/
bool PrintStack(LinkStack S) {StackNode *p=S;if(p==NULL)return false;while(p!=NULL) {printf("%d ",p->data);p=p->Lhead;}
}
一个简单的链栈的基本实现例子
例如,通过链式存储结构创建一个栈,其元素个数为4,为{2,7,0,-3},创建后依次输出从栈顶到栈底的元素值,首先通过输入一个元素,使其进栈,然后读取当前栈顶元素;执行一次出栈操作。然后读取当前栈顶元素,最后再依次输出从栈顶到栈底的元素值,如下代码:
#include<stdio.h>
#include<stdlib.h>typedef struct StackNode {int data;//存放栈中元素struct StackNode *Lhead;//栈顶指针 ,记录栈顶元素的位置
} *LinkStack;//链栈的类型定义/*链栈的初始化,初始化一个空栈*/
bool InitStack(LinkStack &S) {S=NULL;return true;
}/*判断链栈是否为空*/
bool EmptyStack(LinkStack S) {if(S==NULL)return true;elsereturn false;
}/*进栈(插入操作)*/
void PushStack(LinkStack &S, int x) {StackNode *p;p = (StackNode*)malloc(sizeof(StackNode));//动态分配创建一个新结点pp->data = x; //将x放入新结点p的数据域中p->Lhead = S; //将新结点p插入到当前链栈的栈顶前S = p; //将新结点p作为栈顶元素
}/*出栈(删除操作)*/
bool PopStack(LinkStack &S,int &x) {StackNode *p;if(S==NULL)//若栈为空,则报错return false;x=S->data;//x记录当前栈顶元素p=S;//p指针指向原栈顶S=S->Lhead;//S指向下一个结点free(p);//释放栈顶元素return true;
}/*读取链栈的栈顶元素*/
bool GetTopStack(LinkStack &S,int &x) {if(S==NULL)return false;x=S->data;return true;
}/*链栈的建立*/
void CreateStack(LinkStack &S,int x) {int number;printf("请输入要建立的栈中的元素个数:\n");scanf("%d",&number);for(int i=0; i<number; i++) {printf("输入第%d个入栈的元素:\n",i+1);scanf("%d",&x);PushStack(S,x);}
}/*链栈的遍历输出*/
bool PrintStack(LinkStack S) {StackNode *p=S;if(p==NULL)return false;while(p!=NULL) {printf("%d ",p->data);p=p->Lhead;}
}/*主函数*/
int main() {LinkStack S;int x,e; InitStack(S);//初始化 CreateStack(S,x);//创建一个链栈 GetTopStack(S,x);//读取栈顶元素 printf("读取栈顶元素,当前栈顶元素为:%d\n",x);printf("创建的链栈元素从栈顶到栈底依次为:\n");PrintStack(S);printf("\n");printf("输入一个要进栈的元素:\n");scanf("%d",&e);PushStack(S,e);//进栈GetTopStack(S,x);printf("读取栈顶元素,当前栈顶元素为:%d\n",x);PopStack(S,x);//出栈GetTopStack(S,x);printf("执行一次出栈操作后,当前栈顶元素为:%d\n",x);printf("此时链栈元素从栈顶到栈底依次为:\n");PrintStack(S);
}
运行结果如下:
数据结构学习笔记——链式存储结构实现栈(链栈)相关推荐
- 数据结构与算法——栈的链式存储结构及实现
目录 前言 一.栈的链式储存结构 二.栈的链式储存结构的操作 2.1 进栈操作 2.2 出栈操作 总结 前言 讲完了栈的顺序储存结构,我们现在来看看栈的链式存储结构,简称为链栈. 由于单链表中 ...
- 栈的链式存储结构及实现
今天学习栈的链式存储结构. 链式存储结构最大的好处就是没有空间的限制,通过指针指向将结点像一个链子一样把结点链接,那么栈的同样可以用于链式存储结构. 栈的链式存储结构,简称为链栈.想想看,栈只是栈顶来 ...
- 实验一 链式存储结构的基本操作
广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A) 2019年4月27日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术172班 姓名 xxx 学号 17061 ...
- 什么是线性表?什么是线性表的顺序存储结构?什么是线性表的链式存储结构?
1.线性表是最简单也是最常用的一种数据结构.线性表的例子不胜枚举,例如,英文字母表就是一个线性表,表中的英文字母是一个数据元素. 2.线性表的定义:线性表是具有相同特性的数据元素的一个有限序列. 3. ...
- 链式存储mysql_链栈:栈的链式存储结构
前面讲完了栈的顺序存储结构,我们现在来看看栈的链式存储结构,简称为链栈. 链栈是没有附加头结点的运算受限的单链表.栈顶指针就是链表的头指针. 栈是用栈顶来做插入和删除操作,那么对于链栈的栈顶放在链表的 ...
- 3.2_栈_链式存储结构(链表形式)
[链式存储结构] 栈的链式存储结构,简称链栈. [具体实现] package com.Higgin.LinkStack;import java.util.EmptyStackException;/** ...
- 队列的定义、循环队列的顺序存储结构及链式存储结构
文章目录 1 队列的定义 1.1 文字定义 1.2 代码定义 2 循环队列 2.1 循环队列的定义 2.2 循环队列的顺序存储结构 3 队列的链式存储结构 3.1 链队列的入队操作 3.2 链队列的出 ...
- 《数据结构》c语言版学习笔记——单链表结构(线性表的链式存储结构Part1)
线性表的链式存储结构 数据结构系列文章 第二章 单链表结构 文章目录 线性表的链式存储结构 前言 一.单链表的建立 代码 二.单链表的读取 代码 三.单链表的插入 代码 四.单链表的删除 代码 五.单 ...
- 《数据结构》c语言版学习笔记——其他链表(线性表的链式存储结构Part2)
线性表的链式存储结构 数据结构系列文章 第三章 循环链表.双向链表 文章目录 线性表的链式存储结构 前言 一.循环链表 (一)定义 (二)尾指针 二.双向链表 (一)定义 (二)代码 总结 前言 提示 ...
最新文章
- 重新捡起flask(二)
- VMware 如何通过现有虚拟机克隆新的虚拟机
- QML on Android 在小米5s手机上中文字体显示异常
- 比较常用的10个markdown标签
- was、ihs、 mq、 db2的版本查询
- c语言格式化输入字符型,C语言——字符串和格式化输入/输出
- JupyterNotebook随记(part1)--打开默认目录
- linux处理机调度实验报告,模拟Linux操作系统下处理机调度实验报告
- windowsterminal设置初始大小_这是我见过最全面的金蝶操作详解了,从初始化到财务使用全流程...
- 2019 互联网月饼大赏!阿里开动物园,腾讯秀表情包,网易游戏最会玩!
- vs code 前端如何以服务器模式打开 [安装服务器] server insteall
- i18n调用自己参数_Spring Boot :I18N
- HashMap内部存储实现及HashTable比较
- Invalid ADAPTORNAME specified. Type 'imaqhwinfo' for a list of available ADAPTORNAMEs. Image acquis
- 2019年美赛C题思路详解
- 二进制转8421bcd码_绝对值编码器当中的格雷码
- gvim 换行符替换
- 利用Python实现图片信息隐藏
- PBR之IBL和球谐的梳理
- 添加js代码:百度网盘网页版开倍速