目录

  • 一、链栈的定义
  • 二、链栈的初始化
  • 三、判断链栈是否为空栈
  • 四、进栈(插入操作)
  • 五、出栈(删除操作)
  • 六、读取链栈的栈顶元素
  • 七、链栈的建立
  • 八、链栈的遍历输出
  • 链式存储结构实现栈完整代码
    • 一个简单的链栈的基本实现例子

一、链栈的定义

  • 有两种方式实现栈,分别是顺序存储结构和链式存储结构,这里我们把通过链式存储结构实现的栈成为链栈,链栈相对于顺序栈其最大优势是可以动态地分配存储空间,所以通常不会出现栈满的情况,这里我们通过不带头结点的单链表实现链栈(是因为栈的主要操作都是在栈顶进行操作的),即第一个结点设为栈顶从而方便操作。

如下图,也就是一个不带头结点的单链表,即不带头结点的链栈,其中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);
}

运行结果如下:

数据结构学习笔记——链式存储结构实现栈(链栈)相关推荐

  1. 数据结构与算法——栈的链式存储结构及实现

    目录 前言 一.栈的链式储存结构 二.栈的链式储存结构的操作 2.1   进栈操作 2.2   出栈操作 总结 前言 讲完了栈的顺序储存结构,我们现在来看看栈的链式存储结构,简称为链栈. 由于单链表中 ...

  2. 栈的链式存储结构及实现

    今天学习栈的链式存储结构. 链式存储结构最大的好处就是没有空间的限制,通过指针指向将结点像一个链子一样把结点链接,那么栈的同样可以用于链式存储结构. 栈的链式存储结构,简称为链栈.想想看,栈只是栈顶来 ...

  3. 实验一 链式存储结构的基本操作

    广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A) 2019年4月27日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术172班 姓名 xxx 学号 17061 ...

  4. 什么是线性表?什么是线性表的顺序存储结构?什么是线性表的链式存储结构?

    1.线性表是最简单也是最常用的一种数据结构.线性表的例子不胜枚举,例如,英文字母表就是一个线性表,表中的英文字母是一个数据元素. 2.线性表的定义:线性表是具有相同特性的数据元素的一个有限序列. 3. ...

  5. 链式存储mysql_链栈:栈的链式存储结构

    前面讲完了栈的顺序存储结构,我们现在来看看栈的链式存储结构,简称为链栈. 链栈是没有附加头结点的运算受限的单链表.栈顶指针就是链表的头指针. 栈是用栈顶来做插入和删除操作,那么对于链栈的栈顶放在链表的 ...

  6. 3.2_栈_链式存储结构(链表形式)

    [链式存储结构] 栈的链式存储结构,简称链栈. [具体实现] package com.Higgin.LinkStack;import java.util.EmptyStackException;/** ...

  7. 队列的定义、循环队列的顺序存储结构及链式存储结构

    文章目录 1 队列的定义 1.1 文字定义 1.2 代码定义 2 循环队列 2.1 循环队列的定义 2.2 循环队列的顺序存储结构 3 队列的链式存储结构 3.1 链队列的入队操作 3.2 链队列的出 ...

  8. 《数据结构》c语言版学习笔记——单链表结构(线性表的链式存储结构Part1)

    线性表的链式存储结构 数据结构系列文章 第二章 单链表结构 文章目录 线性表的链式存储结构 前言 一.单链表的建立 代码 二.单链表的读取 代码 三.单链表的插入 代码 四.单链表的删除 代码 五.单 ...

  9. 《数据结构》c语言版学习笔记——其他链表(线性表的链式存储结构Part2)

    线性表的链式存储结构 数据结构系列文章 第三章 循环链表.双向链表 文章目录 线性表的链式存储结构 前言 一.循环链表 (一)定义 (二)尾指针 二.双向链表 (一)定义 (二)代码 总结 前言 提示 ...

最新文章

  1. 重新捡起flask(二)
  2. VMware 如何通过现有虚拟机克隆新的虚拟机
  3. QML on Android 在小米5s手机上中文字体显示异常
  4. 比较常用的10个markdown标签
  5. was、ihs、 mq、 db2的版本查询
  6. c语言格式化输入字符型,C语言——字符串和格式化输入/输出
  7. JupyterNotebook随记(part1)--打开默认目录
  8. linux处理机调度实验报告,模拟Linux操作系统下处理机调度实验报告
  9. windowsterminal设置初始大小_这是我见过最全面的金蝶操作详解了,从初始化到财务使用全流程...
  10. 2019 互联网月饼大赏!阿里开动物园,腾讯秀表情包,网易游戏最会玩!
  11. vs code 前端如何以服务器模式打开 [安装服务器] server insteall
  12. i18n调用自己参数_Spring Boot :I18N
  13. HashMap内部存储实现及HashTable比较
  14. Invalid ADAPTORNAME specified. Type 'imaqhwinfo' for a list of available ADAPTORNAMEs. Image acquis
  15. 2019年美赛C题思路详解
  16. 二进制转8421bcd码_绝对值编码器当中的格雷码
  17. gvim 换行符替换
  18. 利用Python实现图片信息隐藏
  19. PBR之IBL和球谐的梳理
  20. 添加js代码:百度网盘网页版开倍速

热门文章

  1. PCB孔铜厚度标准及成品铜厚构成、由来
  2. learning from the Trenches 12-16 用看板管理大型项目
  3. 计算机请假,计算机学院2020请假条模板(短期临时专用).docx
  4. 从Windows过渡到Mac需要注意的那些事儿!
  5. 打造木纹图片效果的PS滤镜教程
  6. 计算机认识键盘的教案,《认识键盘》的教学设计
  7. 解决kde 桌面环境,触摸板手指轻触无法使用的问题
  8. oracle健康巡检脚本,oracle 巡检脚本
  9. 四国军旗辅助记忆小工具
  10. 香橙派pi5安装debian操作系统