栈和队列是两种重要的线性结构,从数据结构的角度看,栈和队列也是线性表,其特殊性在于栈和队列的基本操作是线性表的子集。他们是操作受限的线性表,因此,可称为限定性的数据结构。但从数据类型角度看,他们是和线性表大不相同的两类重要的的抽象数据类型。

文章目录

  • C语言中的栈
    • 栈的定义
    • C语言中栈的基本操作
      • 栈的初始化
      • 判断是否为空栈
      • 判断是否为满栈
      • 入栈
      • 出栈
      • C语言实现栈的具体代码
  • C++中的栈
    • C++中栈的基本操作
      • 初始化
      • 判断是否为空栈
      • 入栈
      • 出栈
      • 返回栈顶元素
      • 返回栈中元素数目

C语言中的栈

栈的定义

栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说,表尾端称为栈顶(top),表头端称为栈低(bottom)。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除,所以栈又被称为后进先出的线性表(简称LIFO:Last in, First out.结构)。

C语言中栈的基本操作

栈的基本操作主要有:栈的初始化、判空、判满、取栈顶元素、在栈顶进行插入和删除。在栈顶插入元素称为入栈,在栈顶删除元素称为出栈。

栈的初始化

栈和线性表类似,也有两种存储表示方法顺序栈和链栈,链栈的操作是线性表操作的特例,操作比较容易实现。顺序栈即栈的顺序存储结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置,top = 0表示空栈。由于栈在使用的过程中所需要的大小难以估计,所以通常是先为栈分配一个基本容量,然后再使用的过程中,当栈的空间不够使用的时候再继续追加存储空间。我们以下述类型说明作为顺序栈的定义:

typedef struct{SDataType *base; //栈底指针SDataType *top;  //栈顶指针int StackSize;   //当前已经分配的存储空间,以元素为单位
}SqStack;

栈的初始化操作为:按照设定的初始分配量进行第一次存储分配,这里使用==malloc()==函数来分配存储空间。malloc()函数的详细说明请看:malloc详细说明。base作为栈底指针,它始终指向栈底,所以s.top = s.base可以作为栈空的标记。top为栈顶指针,top的初值指向栈底。每当插入一个元素时top加1,弹出一个元素时top减1,因此,非空栈中的栈顶指针始终在栈顶元素的下一个位置上

//初始化顺序栈,构造一个空栈
Status InitStack(SqStack &S){//分配存储空间 S.base = (SDataType *)malloc(STACK_INIT_SIZE*sizeof(SDataType));if(!S.base){//如果分配失败,则返回error return OVERFLOW;}//S.top 始终指向栈顶元素的下一个位置 S.top = S.base;    //初始状态下为空栈 S.StackSize = STACK_INIT_SIZE;   //当前已经分配的存储容量为100个 return OK;
}

判断是否为空栈

当我们弹出栈顶元素时,往往需要判断一下栈是否为空来防止发生下溢。上面我们说到==base作为栈底指针,它始终指向栈底,所以s.top = s.base可以作为栈空的标记。==所以我们可以这样判断栈是否为空:

//判断是否为空栈
void judgeNull(SqStack &s){if(s.top == s.base){printf("此栈为空栈!\n");}else{printf("此栈不为空栈!\n");}
}

判断是否为满栈

当我们使一个元素入栈的之前,我们往往需要判断一下栈是否为满栈,防止发生上溢的情况。因为我们定义了一个StackSize来表示当前已经分配的存储空间,所以我们可以用s.top - s.base 来算出当前已经使用的栈空间。所以当s.top - s.base == s.StackSize 时表示已经满栈:

//判断是否为满栈
void judgeFull(SqStack &s){if(s.top-s.base == s.StackSize){printf("栈满!\n");}else{printf("栈未满!\n");}
}

入栈

入栈时我们首先要判断栈是否为满栈,如果为满栈我们要首先追加存储空间,然后才能将元素入栈。realloc()函数详解请看realloc详解

//入栈
Status Push(SqStack &s,SDataType e){SDataType *p;//首先判断栈是不是满的(上溢) if(s.top-s.base == s.StackSize){//追加空间 p = (SDataType *)realloc(s.base,(s.StackSize + STACKINCREMENT)*sizeof(SDataType));if(!p){//如果没有找到符合条件的存储空间,则返回error return OVERFLOW;}//成功找到则使s.base指向p s.base = p;s.top = s.base + s.StackSize;s.StackSize +=  STACKINCREMENT;}//先插入元素,然后将栈顶指针加 1 *(s.top) = e;s.top++;return OK;
}

出栈

出栈时我们首先要判断栈是否为空栈。如果栈已经空了,则返回error。

//出栈
Status Pop(SqStack &s,SDataType &e){//判断是否会发生下溢 if(s.top != s.base){s.top--;    //先将栈顶指针减 1 e = *(s.top);}else{return 0;}return e;
}

C语言实现栈的具体代码

#include<stdio.h>
#include<malloc.h>#define STACK_INIT_SIZE 100  //栈的初始容量
#define STACKINCREMENT 10    //容量增量
#define OK 1
#define OVERFLOW -2
typedef int SDataType;
typedef int Status;typedef struct{SDataType *base; //栈底指针SDataType *top;  //栈顶指针int StackSize;   //当前已经分配的存储空间,以元素为单位
}SqStack;//初始化顺序栈,构造一个空栈
Status InitStack(SqStack &S){//分配存储空间 S.base = (SDataType *)malloc(STACK_INIT_SIZE*sizeof(SDataType));if(!S.base){//如果分配失败,则返回error return OVERFLOW;}//S.top 始终指向栈顶元素的下一个位置 S.top = S.base;    //初始状态下为空栈 S.StackSize = STACK_INIT_SIZE;   //当前已经分配的存储容量为100个 return OK;
} //入栈
Status Push(SqStack &s,SDataType e){SDataType *p;//首先判断栈是不是满的(上溢) if(s.top-s.base == s.StackSize){//追加空间 p = (SDataType *)realloc(s.base,(s.StackSize + STACKINCREMENT)*sizeof(SDataType));if(!p){//如果没有找到符合条件的存储空间,则返回error return OVERFLOW;}//成功找到则使s.base指向p s.base = p;  //系统会将原来的内容复制过来s.top = s.base + s.StackSize;s.StackSize +=  STACKINCREMENT;}//先插入元素,然后使栈顶指针加 1 *(s.top) = e;s.top++;return OK;
} //出栈
Status Pop(SqStack &s,SDataType &e){//判断是否会发生下溢 if(s.top != s.base){s.top--;    //先将栈顶指针减 1 e = *(s.top);}else{return 0;}return e;
}//判断是否为空栈
void judgeNull(SqStack &s){if(s.top == s.base){printf("此栈为空栈!\n");}else{printf("此栈不为空栈!\n");}
}//判断是否为满栈
void judgeFull(SqStack &s){if(s.top-s.base == s.StackSize){printf("栈满!\n");}else{printf("栈未满!\n");}
} int main(){SqStack s;SDataType element;InitStack(s);  //初始化栈//将1-10入栈for(int i=1;i<=10;i++){Push(s,i);}judgeNull(s);judgeFull(s);printf("出栈:\n");//只要栈不为空 while(s.top != s.base){Pop(s,element);    //出栈的元素用e接收 printf("%d ",element);}printf("\n"); judgeNull(s);return 0;}

C++中的栈

C++ 对模板(Template)支持得很好,STL 就是借助模板把常用的数据结构及其算法都实现了一遍,并且做到了数据结构和算法的分离。STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个头文件:<algorithm >、<deque >、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>和<utility>。其中的<stack>就是栈。

C++的STL已经将栈的操作都封装成了函数,我们只需要引进#include<stack>头文件即可使用。

C++中栈的基本操作

初始化

我们可以直接使用stack<int> s;来创建一个空的 stack 对象。

判断是否为空栈

使用empty()函数来判断栈是否为空。

入栈

使用push()函数来完成入栈操作。

出栈

使用pop()函数实现出栈

返回栈顶元素

使用top()函数返回栈顶元素

返回栈中元素数目

使用size()函数返回栈中元素的数目。


以上就是C语言和C++中栈的基本用法了,如果你觉得我的文章对你有用请点个赞支持一下吧,如果喜欢我写的文章那么请点个关注再走。

下一篇将继续写数据结构的队列,后续将会再写一些有关栈和队列的具体应用。我是ACfun:一个成长中的程序猿,感谢大家的支持。

数据结构——栈的详解相关推荐

  1. java语言链栈_Java语言实现数据结构栈代码详解

    近来复习数据结构,自己动手实现了栈.栈是一种限制插入和删除只能在一个位置上的表.最基本的操作是进栈和出栈,因此,又被叫作"先进后出"表. 首先了解下栈的概念: 栈是限定仅在表头进行 ...

  2. c语言 栈结构存放数据类型,数据结构——栈的详解

    栈和队列是两种重要的线性结构,从数据结构的角度看,栈和队列也是线性表,其特殊性在于栈和队列的基本操作是线性表的子集.他们是操作受限的线性表,因此,可称为限定性的数据结构.但从数据类型角度看,他们是和线 ...

  3. 数据结构与算法详解目录

    数据结构与算法详解是一本以实例和实践为主的图书,主要是经典的数据结构与常见算法案例,来自历年考研.软考等考题,有算法思路和完整的代码,最后提供了C语言调试技术的方法. 后续配套微课视频. 第0章  基 ...

  4. 数据结构--图(Graph)详解(四)

    数据结构–图(Graph)详解(四) 文章目录 数据结构--图(Graph)详解(四) 一.图中几个NB的算法 1.普里姆算法(Prim算法)求最小生成树 2.克鲁斯卡尔算法(Kruskal算法)求最 ...

  5. 数据结构--图(Graph)详解(一)

    数据结构–图(Graph)详解(一) 文章目录 数据结构--图(Graph)详解(一) 一.图的基本概念 1.图的分类 2.弧头和弧尾 3.入度和出度 4.(V1,V2) 和 < V1,V2 & ...

  6. 数据结构--图(Graph)详解(三)

    数据结构–图(Graph)详解(三) 文章目录 数据结构--图(Graph)详解(三) 一.深度优先生成树和广度优先生成树 1.铺垫 2.非连通图的生成森林 3.深度优先生成森林 4.广度优先生成森林 ...

  7. 数据结构--图(Graph)详解(二)

    数据结构–图(Graph)详解(二) 文章目录 数据结构--图(Graph)详解(二) 一.图的存储结构 1.图的顺序存储法 2.图的邻接表存储法 3.图的十字链表存储法 4.图的邻接多重表存储法 二 ...

  8. 用数据结构c语言写成绩排序,C语言数据结构 快速排序实例详解

    C语言数据结构 快速排序实例详解 一.快速排序简介 快速排序采用分治的思想,第一趟先将一串数字分为两部分,第一部分的数值都比第二部分要小,然后按照这种方法,依次对两边的数据进行排序. 二.代码实现 # ...

  9. python链表值讲解_python数据结构之链表详解

    python数据结构之链表详解 数据结构是计算机科学必须掌握的一门学问,之前很多的教材都是用C语言实现链表,因为c有指针,可以很方便的控制内存,很方便就实现链表,其他的语言,则没那么方便,有很多都是用 ...

  10. 数据结构之链表详解(2)——双向链表

    目录 前言 一.双向链表 A.双向链表的含义 B.双向链表的实现 1.双向链表的结构 2.链表的初始化 初始化图解: 函数代码: 3.动态申请节点函数 函数代码: 4.打印双向链表函数 函数代码: 5 ...

最新文章

  1. ES6中的Promise详解
  2. VBA赋值给指定单元格
  3. 性价比泛滥后,网易严选情怀路线还能否继续吃香?
  4. 谷歌最终还是把Knative交了出来
  5. Instant类的使用
  6. 可能是最好理解的二叉树的层序遍历
  7. Intellij IDEA中分屏显示方法
  8. LeetCode 1979. 找出数组的最大公约数
  9. Android倒计时案例展示
  10. 第9章 SportsStorePeta 完成购物车
  11. 多个容器一起打包_Docker从入门到掉坑(三):容器太多,操作好麻烦
  12. TCP 和 UDP 区别
  13. 证件照尺寸大小收集整理
  14. Blender建模练习:人物模型多边形建模流程图解(二形体调整篇)
  15. 【图形学】计算网格中两点连成的直线所经过的格子
  16. java实现12306查票_java抓取12306信息实现火车余票查询示例
  17. 西达摩花魁咖啡豆名字来源
  18. 使用xib自定义button
  19. Android代码混淆工具Proguard学习
  20. 微软发布2010年度经典MSN签名

热门文章

  1. Redis队列和专业MQ的对比和选型
  2. 批量查排名的工具有哪些?网站关键词可以优化?
  3. 腾讯课堂视频回放下载(Edge浏览器+猫抓+夸克浏览器)
  4. 苹果鼠标怎么充电_macbook pro搭配什么鼠标好?
  5. 关于“应用程序正常初始化(0xc0150002)失败”问题的解决方案
  6. 小程序毕业设计 基于微信考试小程序毕业设计开题报告功能参考
  7. csharp进阶练习题:谜机 - 第1部分:插板【难度:2级】--景越C#经典编程题库,不同难度C#练习题,适合自学C#的新手进阶训练
  8. python寻找所有三位数素数_寻找所有的素数的python实现
  9. centos 文件搜索命令
  10. photoshop技巧分享:psd格式批量转换jpg格式一键完成