[C语言数据结构]栈
目录
1.栈的定义:
1.2栈的特性:
1.3栈的实现:
1.4代码:
1.4.1结构的声明:
1.4.2栈的初始化:
代码:
1.4.3入栈:
代码:
1.4.4出栈
void StackPop(ST* ps);
代码:
1.4.6栈的大小
int StackSize(ST* ps);
这个函数返回的是栈的大小,只需要将top返回即可;代码:
1.4.8栈的销毁
2.完整代码
源文件:
头文件
test.c
1.栈的定义:
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/入栈,插入数据是在栈顶操作;
出栈:栈的删除操作叫做出栈,出数据也在栈顶;
1.2栈的特性:
先进后出
栈的最经典的特性就是先进后出,也可以被叫做后进先出;
这怎么理解呢,就相当于是枪的弹夹,在填装子弹的时候和取出子弹的时候,我们会发现最先放进去的子弹反而是被最后取出的,而最后放入的子弹是最先放进去的;
1.3栈的实现:
分析:对于栈的实现来说,我们有两种数据结构可待选择;
一种是链表,一种是数组;
对于栈的话我们要进行的最多的就是出栈和入栈的操作了。
首先我们来讲数组:数组对于实现入栈出战来说还是很方便的,特别是选用尾部为栈顶的话。只需要的就是数组的扩容问题,只需要调用realloc函数即可。
再其次是链表:对于链表的话我们如果选用单链表的话,若是选用尾部为栈顶的话,我们就很麻烦,每次都需要遍历找到链表的尾指针;
而且相对来说数组的尾插和尾删的效率都很高。
所以这里我们选择先使用数组来实现栈;
1.4代码:
1.4.1结构的声明:
首先我们来分析对于一个用数组来实现的栈来说,我们只需要有一个数组指针,标记栈顶位置的变量,和一个记录栈的容量的变量;
typedef int STDataType; typedef struct Stack {STDataType* a;int top;int capacity; }ST;
1.4.2栈的初始化:
void StackInit(ST* ps);这个函数我们实现的是对于栈的初始化,这个函数的参数是一个结构体类型的指针,我们只需要将结构体内部包含的一个数组指针置空,和两个分别表示栈顶位置的变量和栈的容量的变量都置成零即可。
这里有一个要注意的点就是我们把top也置为0,就是表示top每次指向的是栈顶的后一个位置;(这一点很重要后面的出栈和入栈都会用到)
代码:
//栈的初始化 void StackInit(ST* ps) {assert(ps);ps->a = NULL;ps->top = 0;ps->capacity = 0; }
1.4.3入栈:
void StackPush(ST* ps, STDataType x);
这个函数来试下入栈的操作,对于入栈来说我们最需要注意的就是空间问题,因为数组的大小是给固定的所以我们要在每次入栈的时候要进行一次判断,判断是否需要扩容,并且这里要注意的是top指的是栈顶的后一个位置,所以我们执行的是先插入数据后,再将top++的;
代码:
//入栈 void StackPush(ST* ps, STDataType x) {assert(ps);if (ps->top == ps->capacity){int newCapacity = (ps->capacity == 0 ? 4 : ps->capacity * 2);STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++; }
1.4.4出栈
void StackPop(ST* ps);
对于数组实现的栈来说,出栈的操作非常简单,我们只需要将记录栈顶的位置的变量top--即可。
代码:
//出栈 void StackPop(ST* ps) {assert(ps);assert(!StackEmpty(ps));ps->top--; }
1.4.5拿到栈顶的数据
STDataType StackTop(ST* ps);这个函数实现的就是返回栈顶的数据,只需要将数组中对应栈顶的数据返回即可,这里需要注意的就是,在返回栈顶数据的时候数组的下标用的是top-1;
代码:
//拿到栈顶的数据 STDataType StackTop(ST* ps) {assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top - 1]; }
1.4.6栈的大小
int StackSize(ST* ps);
这个函数返回的是栈的大小,只需要将top返回即可;
代码://栈的大小 int StackSize(ST* ps) {assert(ps);return ps->top; }
1.4.7判断栈是否为空
bool StackEmpty(ST* ps);如果栈的空间是空,我们就返回假,如果栈的空间是不为空,就返回真;
代码://栈是否为空 bool StackEmpty(ST* ps) {assert(ps);return ps->top == 0; }
1.4.8栈的销毁
void StackDestroy(ST* ps);
将数组指针置空,然后其他变量置为0即可;
代码:
//栈的销毁 void StackDestroy(ST* ps) {assert(ps);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->top = 0; }
以上就是栈用数组的实现了!
这里再推荐一个用到栈的力扣题大家可以去试一试练练手:
20. 有效的括号 - 力扣(LeetCode)
2.完整代码
源文件:
#define _CRT_SECURE_NO_WARNINGS 1
#include"stack.h"
//栈的初始化
void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->top = 0;ps->capacity = 0;}//入栈
void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){int newCapacity = (ps->capacity == 0 ? 4 : ps->capacity * 2);STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}//栈的销毁
void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}//出栈
void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));ps->top--;
}//拿到栈顶的数据
STDataType StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top - 1];
}//栈的大小
int StackSize(ST* ps)
{assert(ps);return ps->top;
}//栈是否为空
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
头文件
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;//栈的初始化
void StackInit(ST* ps);//栈的销毁
void StackDestroy(ST* ps);//入栈
void StackPush(ST* ps, STDataType x);//出栈
void StackPop(ST* ps);//拿到栈顶的数据
STDataType StackTop(ST* ps);//栈的大小
int StackSize(ST* ps);//栈是否为空
bool StackEmpty(ST* ps);
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"stack.h"void Teststack()
{ST st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);while (!StackEmpty(&st)){printf("%d ", StackTop(&st));StackPop(&st);}StackDestroy(&st);}int main()
{Teststack();return 0;
}
以上就是本篇博客的所有内容了,如果帮到你请点赞关注收藏一下!
[C语言数据结构]栈相关推荐
- 11.0、C语言数据结构——栈
11.0.C语言数据结构--栈 栈的定义: 栈是一种重要的线性结构,可以这样讲,栈是前面讲过的线性表的一种具体形式: 官方定义:栈(stack)是一个 后进先出(Las ...
- c语言特殊计算器设计报告,C语言数据结构栈计算器的实现课题设计报告书
C语言数据结构栈计算器的实现课题设计报告书 (13页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 目录1. 课程设计任务 12. 需求分析 ...
- C语言数据结构-栈的使用及实例
本文主要讨论C语言数据结构的又一重要结构--栈 一.栈的理论知识 1. 定义和特点 定义:只允许在一端插入和删除的线性表:允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom). 特点 ...
- c语言栈中符号 的作用是什么,C语言数据结构----栈的应用(程序的符号匹配检测)...
本节主要讲利用栈来实现一个程序中的成对出现的符号的检测,完成一个类似编译器的符号检测的功能,采用的是链式栈. 一.问题的提出以及解决方法 1.假定有下面一段程序: #include #include ...
- C语言-数据结构-栈(静态栈与动态栈)
一.简介 在哔哩哔哩看视频学的,赫斌老师数据结构入门的内容-b站搜索:av6159200(P33),通过学习,能独立把赫斌老师教的敲出来,由于动态栈(链表阉割版)的功能很少,我并没有增加什么其它功能, ...
- C语言 数据结构 栈的数组实现 realloc函数
主题:栈的数组实现 功能:分别栈的入栈.弹栈.打印操作 提示:运行程序自动进入入栈操作,退出入栈,数组3个ctrl z,然后进入出栈操作,输入非n的任意char字符,继续出栈.输入n结束出栈,整个程序 ...
- C语言 数据结构 栈(用链表实现)
疑惑 为什么栈要分两个结构体来创建,而链表只需要一个? 能不能只用一个结构体创建一个栈? 代码 用函数实现了压栈,弹栈,打印栈的操作 #include<stdio.h> #include& ...
- GO语言-数据结构-栈
目录 1.栈的顺序存储实现 1.1结构体定义 1.2 初始化栈 1.3入栈 1.4出栈 1.5完整代码 1.6拓展-一个数组实现两个栈 2.栈的链式存储实现 2.1链栈的结构体定义 2.2链栈的初始化 ...
- C语言 数据结构 栈的应用(括号匹配)
#include<stdio.h> #include<stdlib.h> #define MaxSize 10 #define true 1 #define false 0 t ...
最新文章
- EasyUI表单验证,自定义插件验证,自定义js插件验证,远程验证,常见手机号,中英文,qq等验证规则验证...
- Webstorm 10.0.4 配置
- leetcode面试题 17.15. 最长单词
- Mysql: LBS实现查找附近的人 (两经纬度之间的距离)
- Java 程序 ——感想
- iphone模拟器_iPhone 上玩真的 PSP 游戏,支持 iOS 13 系统
- 【干货】如何从0到1构建用户画像系统.pdf(附76页pdf下载链接)
- win10下安装多个cuda(cuda9.0和10.0),并自由切换版本
- ubuntu中安装sqldeveloper和JDK 1.7
- Open3d之计算源点云与目标云的距离
- 阿里天猫亿级浏览型网站静态化架构演变
- 车载前视摄像头学习笔记 ———— 摄像头输出数据格式(RGB)
- 谈谈创业这点事 之 时间窗口
- vs2017安装qt插件及安装qt插件后的设置
- html自动刷新插件谷歌,Super Auto Refresh:定时自动重新刷新网页
- java中int不兼容_mvn install命令时,一直报错:不兼容的类型 [ERROR] 找到: java.lang.Object [ERROR] 需要: int...
- 计算机网络的基础学习
- H3C路由器交换机配置sflow
- 如何改域的NETBIOS名?
- 2017-2018-2 20155203《网络对抗技术》Exp9 :Web安全基础