栈(操作受限的线性表)---C语言版
目录
- 一、栈的相关概念
- 二、栈的基本操作
- 三、顺序栈
- 3.1 顺序栈的定义
- 3.2 顺序栈的操作
- `InitStack(*S)`:构造一个空栈S
- `StackEmpty(S)`:若栈S为空栈,则返回TRUE,否则为FALSE。
- `Push(*S,e)`:插入元素e为新的栈顶元素
- `Pop(*S,*e)`:删除S的栈顶元素,并用e返回其值。
- `StackLength(S)`:返回栈S的元素个数,即栈的长度。
- `GetTop(S,*e)`:用e返回栈顶元素
- `StackTraverse(S)`:从栈底到栈顶依次遍历栈S,打印其中的元素
- `DestoryStack(*S)`:销毁栈
- `ClearStack(*S)`:栈S清为空栈
- 3.3 完整源码
- 四、链栈
一、栈的相关概念
栈的定义
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表。因此,对于栈来说,表尾端有着特殊含义,称为栈顶(top),相应地,表头段称为栈底(bottom)。不含元素的空表叫做空栈。
栈顶:线性表允许进行插入删除的那一端。
栈底:固定的,不允许进行插入和删除的一端。
空栈:不含任何元素的空表。
栈的操作特性:后进先出(Last In First Out)
假设某个栈S=(a1,a2,…,an),则称a1为栈底元素,an为栈顶元素。
栈中的元素按照a1,a2,…,an的顺序进栈,退栈的第一个元素应为栈顶元素。
换句话说,栈的修改是按后进先出的原则进行的,可以简称为LIFO;
栈的示意图:
栈的数学特性
n个不同的元素进栈,出栈元素不同的排列的个数为1n+1C2nn\frac{1}{n+1}C_{2n}^nn+11C2nn。该公式称为卡特兰数。
二、栈的基本操作
InitStack(*S)
:构造一个空栈SStackEmpty(S)
:若栈S为空栈,则返回TRUE,否则为FALSE。Push(*S,e)
:插入元素e为新的栈顶元素Pop(*S,*e)
:删除S的栈顶元素,并用e返回其值。StackLength(S)
:返回栈S的元素个数,即栈的长度。GetTop(S,*e)
:用e返回栈顶元素StackTraverse(S)
:从栈底到栈顶依次遍历栈S,打印其中的元素DestoryStack(*S)
:销毁栈ClearStack(*S)
:栈S清为空栈
接下来便分为栈的顺序存储和链式存储来实现这些操作。
三、顺序栈
采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素。
3.1 顺序栈的定义
顺序栈实际上也就是操作受限的顺序表,我们这里采用动态分配的方式。关于顺序表的内容,可以查看顺序表(线性表的顺序存储)—C语言版
仍旧使用该例子,我们要如何存储该表呢?
id | name | description |
---|---|---|
1 | 史强 | 最强辅助 |
2 | 章北海 | 我不需要钢印,我是自己思想的主人 |
3 | 罗辑 | 人类不感谢罗辑 |
4 | 维德 | 失去人性,失去很多。失去兽性,失去一切 |
步骤一:声明数据元素类型
首先我们使用结构体声明数据元素(对应表中的一行数据)的类型
typedef struct{int id;//对应表中的idchar name[100];//对应表中的姓名char description[200];//对应表中的描述
}SElemType;//此处的SElemType是个类型名
步骤二:顺序栈的定义
#define InitSize 10;//栈的初始长度
#define ListIncrement 2;//扩容时的分配增量
typedef struct{SElemType *base;//栈的基地址,指示动态分配的数组的指针SElemType *top;//栈顶指针int MaxSize;//当前栈的最大存储长度
}SqStack;//顺序栈的类型定义
3.2 顺序栈的操作
- 栈结构不存在:
base==NULL;
- 栈为空:
base==top
- 入栈:
*top=e; top++;
先赋值再加一 - 出栈:
top--; *e=*top;
先减一再返回
InitStack(*S)
:构造一个空栈S
/*初始化*/
int InitStack(SqStack *S){ S->base=(SElemType *)malloc(sizeof(SElemType)*InitSize); //给栈分配存储空间if(!S->base) return FALSE; //分配失败返回FALSES->top=S->base;//空栈的top和base指向同一个位置S->MaxSize=InitSize;//初始最大长度return TRUE;//成功初始化返回TRUE
}
StackEmpty(S)
:若栈S为空栈,则返回TRUE,否则为FALSE。
/*判断是否为空栈*/
int StackEmpty(SqStack S){if (S.base==S.base) return TRUE;return FALSE;
}
Push(*S,e)
:插入元素e为新的栈顶元素
/*插入*/
int Push(SqStack *S,SElemType e){if(S->top-S->base>=S->MaxSize){S->base=(SElemType*)realloc(S->base,(S->MaxSize+StackIncrement)*sizeof(SElemType));//栈满追加存储空间if (!S->base) return FALSE;//存储分配失败S->top=S->base;S->MaxSize+=StackIncrement;}*S->top++=e;//先赋值再加一return TRUE;
}
Pop(*S,*e)
:删除S的栈顶元素,并用e返回其值。
/*删除*/
int Pop(SqStack *S,SElemType *e){ if (S->top==S->base) return FALSE;//如果栈为空,返回*e=*(--S->top);//先减一再返回 return TRUE;
}
StackLength(S)
:返回栈S的元素个数,即栈的长度。
/*求栈长*/
int StackLength(SqStack S){int length=0;for( ;S.base<S.top;S.base++){length++;}return length;
}
GetTop(S,*e)
:用e返回栈顶元素
/*获取栈顶元素*/
int GetTop(SqStack S,SElemType *e){if (S.top==S.base) return FALSE;*e=*(S.top-1);return TRUE;
}
StackTraverse(S)
:从栈底到栈顶依次遍历栈S,打印其中的元素
/*打印*/
void StackTraverse(SqStack S){for ( ;S.base<S.top;S.base++){printf("id=%d,name=%s,description=%s\n",S.base->id,S.base->name,S.base->description);}
}
DestoryStack(*S)
:销毁栈
/*销毁顺序表*/
void DestroyStack(SqStack *S){free(S->base);S->MaxSize=0;S->base=NULL;S->top=NULL;
}
ClearStack(*S)
:栈S清为空栈
/*清空栈*/
void ClearStack(SqStack *S){S->top=S->base;
}
3.3 完整源码
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define InitSize 10 //表的初始长度
#define StackIncrement 2 //扩容时的分配增量
typedef struct{int id;//对应表中的idchar name[100];//对应表中的姓名char description[200];//对应表中的描述
}SElemType;//此处的SElemType是个类型名typedef struct{SElemType *base;//栈的基地址,指示动态分配的数组的指针SElemType *top;//栈顶指针int MaxSize;//当前栈的最大存储长度
}SqStack;//顺序栈的类型定义/*初始化*/
int InitStack(SqStack *S){ S->base=(SElemType *)malloc(sizeof(SElemType)*InitSize); //给栈分配存储空间if(!S->base) return FALSE; //分配失败返回FALSES->top=S->base;//空栈的top和base指向同一个位置S->MaxSize=InitSize;//初始最大长度return TRUE;//成功初始化返回TRUE
}
int StackEmpty(SqStack S){if (S.base==S.base) return TRUE;return FALSE;
}/*插入*/
int Push(SqStack *S,SElemType e){if(S->top-S->base>=S->MaxSize){S->base=(SElemType*)realloc(S->base,(S->MaxSize+StackIncrement)*sizeof(SElemType));//栈满追加存储空间if (!S->base) return FALSE;//存储分配失败S->top=S->base;S->MaxSize+=StackIncrement;}*S->top++=e;//先赋值再加一return TRUE;
} /*删除*/
int Pop(SqStack *S,SElemType *e){ if (S->top==S->base) return FALSE;//如果栈为空,返回*e=*(--S->top);return TRUE;
}/*求栈长*/
int StackLength(SqStack S){int length=0;for(;S.base<S.top;S.base++){length++;}return length;
}/*获取栈顶元素*/
int GetTop(SqStack S,SElemType *e){if (S.top==S.base) return FALSE;*e=*(S.top-1);return TRUE;
}/*打印*/
void StackTraverse(SqStack S){for ( ;S.base<S.top;S.base++){printf("id=%d,name=%s,description=%s\n",S.base->id,S.base->name,S.base->description);}
}/*销毁顺序表*/
void DestroyStack(SqStack *S){free(S->base);S->MaxSize=0;S->base=NULL;S->top=NULL;
}/*清空栈*/
void ClearStack(SqStack *S){S->top=S->base;
}int main(void){///初始化SqStack S;int i=InitStack(&S);if (i==1){printf("初始化成功\n");}else{printf("初始化失败\n"); }printf("\n");
///插入SElemType a[4]={{1,"史强","最强辅助"},{2,"章北海","我不需要钢印,我是自己思想的主人"},{3,"罗辑","人类不感谢罗辑"},{4,"维德","失去人性,失去很多。失去兽性,失去一切"}};int j;for ( j = 0; j < 4; j++){i=Push(&S,a[j]);}StackTraverse(S);printf("\n");
删除SElemType e;Pop(&S,&e); printf("被删除的元素:id=%d,name=%s,description=%s\n",e.id,e.name,e.description);printf("删除之后:\n");StackTraverse(S);printf("\n");
//获取栈顶元素i=GetTop(S,&e);printf("栈顶元素:id=%d,name=%s,description=%s\n",e.id,e.name,e.description);printf("\n");
//销毁查找 DestroyStack(&S);StackTraverse(S);//打印为空了
}
运行结果:
初始化成功id=1,name=史强,description=最强辅助
id=2,name=章北海,description=我不需要钢印,我是自己思想的主人
id=3,name=罗辑,description=人类不感谢罗辑
id=4,name=维德,description=失去人性,失去很多。失去兽性,失去一切被删除的元素:id=4,name=维德,description=失去人性,失去很多。失去兽性,失去一切
删除之后:
id=1,name=史强,description=最强辅助
id=2,name=章北海,description=我不需要钢印,我是自己思想的主人
id=3,name=罗辑,description=人类不感谢罗辑栈顶元素:id=3,name=罗辑,description=人类不感谢罗辑
四、链栈
栈(操作受限的线性表)---C语言版相关推荐
- DS007-队列的原理-操作受限的线性表-queue的使用
本篇介绍基于顺序表的队列和基于单链表的队列的原理和实现. 最后介绍一下C++ STL 模板库 queue的使用. 一.什么是队列 有些应用,处理的对象是线性关系,用线性表存储, 但这些应用又有自己的特 ...
- 栈和队列以及线性表的区别
1.队列先进先出,栈先进后出. 2.对插入和删除操作的"限定". 栈是限定只能在表的一端进行插入和删除操作的线性表.队列是限定只能在表的一端进行插入和在另一端进行删除操作的线性表. ...
- 数据结构摧毁线性表用c语言,[简述]数据结构-线性表(c语言实现)
[简述]数据结构-线性表(c语言实现)second60 20180422 1. 线性表的定义 线性表是具有相同特性的数据元素的一个有限序列. 2. 线性表抽象数据类型描述 ADT List { 数据 ...
- 用标准C语言初始化线性表,C语言数据结构-顺序线性表的实现-初始化、销毁、长度、查找、前驱、后继、插入、删除、显示操作...
1.数据结构-顺序线性表的实现-C语言 #define MAXSIZE 100 //结构体定义 typedef struct { int *elem; //基地址 int length; //结构体当 ...
- 进栈顺序为abcd则出栈顺序为_线性表之顺序表示
线性表 1. 线性表的基础知识 1.1 线性表的定义 线性表是具有相同数据类型的n(n>0)个数据元素的有限序列. 若用L命名,表示:L=(a1,a2,a3,-,ai-1,ai,ai+1,-,a ...
- 线性表C语言locate和ETget,线性表(数据结构重难点讲解)
<线性表(数据结构重难点讲解)>由会员分享,可在线阅读,更多相关<线性表(数据结构重难点讲解)(104页珍藏版)>请在人人文库网上搜索. 1.线性表(数据结构重难点讲解)导读: ...
- 线性表 c++语言代码,线性表C++的两种实现(顺序表示、单链表)
[C++] 纯文本查看 复制代码bool InitList(LinkList &L) { L = new LNode; if (L == NULL) return false; L->n ...
- 图书信息管理系统(数据结构顺序表,c语言版)
图书信息管理系统 顺序表 一.实验题目 二.工具环境 三.实验问题 问题: 四.实验代码 五.解决方法 方法: 一.实验题目 图书信息管理系统 出版社有一些图书数据,为简单起见,在此假设每种图书只包括 ...
- C语言做线性分析,C语言版的线性回归分析函数
前几天,清理出一些十年以前 DOS 下的程序及代码,看来目前也没什么用了,想打个包刻在光碟上,却发现有些代码现在可能还能起作用,其中就有计算一元回归和多元回归的代码,一看代码文件时间,居然是 1993 ...
最新文章
- Handler实现与机制 Blocking Queue IdleHandler使用
- 计算机系统基础:输入输出技术知识笔记
- kafka分区与分组原理_kafka 基本原理和概念
- java redis 故障切换_java使用Redis6–sentinel单点故障主从自动切换
- Wayland 协议的解析
- Try-Catch 包裹的代码异常后,竟然导致了产线事务回滚!| 原力计划
- python tab键自动补全_设置python中TAB键自动补全方法
- ZOJ 1094 带括号的矩阵连乘
- c++坦克大战 代码免费复制(附源码)
- matlab latex表示,科学网—MATLAB程序如何在latex上发表? - 卢远志的博文
- 【基础学习】操作系统学习笔记 - 内存管理:内存使用与分段、内存分区与分页、多级页表、快表、段页式内存管理的实现、内存的换入换出
- 概念讲解:大地水准面 | 地球椭球体 | 参考椭球体 | 大地基准面 | 地图投影
- 获取局域网电脑的硬件配置
- 皮尔逊相关系数公式手写代码【Python+详细注解】(Pearson correlation coefficient)
- Adobe国际认证让科技赋能时尚
- Vue中相同逻辑如何抽离?
- 苹果手机显示没有连接服务器怎么办啊,苹果手机更新连接到服务器出现问题怎么办...
- GreenPlum数据库卸数、装数
- docker 安装 shipyard(中文版) 集群管理平台
- 随便写的:新戏剧之王,一部广义上的烂片观后感
热门文章
- ffmpeg (三):ffmpeg结合SDL2.0解码音频流
- ios ffmpeg(libfdk-aac) aac encode
- VTDecompressionSessionDecodeFrame -8969
- ubuntu-常用命令汇总
- sobel算子_边缘检测算法4.-教你动手实现kirsch和robinson算子
- python精确有理数实验_Python3标准库:fractions有理数
- mac 看端口占用并杀死进程
- 已解决:Cannot find ./catalina.sh The file is absent or does not have execute permission This file is ne
- 修改鼠标手形 闪烁 在填写文字内容后也一直在闪烁
- centos java 路径_CentOS JAVA安装及查看路径方法