数据结构之栈

这篇具有很好参考价值的文章主要介绍了数据结构之栈。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Stack

类型定义

栈是限定仅在表尾进行插入和删除操作的线性表,又称为后进先出(last in first out)的线性表(LIFO结构),表尾称为栈顶,表头称为栈底,不含元素则称为空栈;
抽象数据类型:

InitStack(&S)               //构造空栈S
DestoryStack(&S)            //销毁栈S
ClearStack(&S)              //将S清为空栈
StackEmpty(S)               //若S为空栈返回TRUE,否则FALSE
StackLength(S)              //返回栈S的元素个数,即栈的长度
GetTop(S, &e)               //用e返回S的栈顶元素
Push(&S, e)                 //插入元素e为新的栈顶元素
Pop(&S, &e)                 //删除S的栈顶元素,并用e返回其值
StackTraverse(S, visit())   //从栈顶到栈底依次对S的每个元素调用visit(),visit()失败则操作失败

顺序存储结构

存储表示

其中base为NULL时表示栈结构不存在,top==base可作为栈空的标记;

#define STACK_INIF_SIZE 100  //存储空间初始分配量
#define STACKINCREMENT 10    //存储空间分配增量
#define OK 1
#define ERROR 0

typedef int SElemType;
typedef int Status;

typedef struct
{
  SElemType *base;            //栈不存在为NULL
  SElemType *top;
  int stacksize;
}SqStack;

基本实现

InitStack

Status InitStack(SqStack *S)
{ // 构造空栈S
  S->base = (SElemType *)malloc(STACK_INIF_SIZE * sizeof(SElemType));
  if (!S->base)
    return ERROR;
  S->top = S->base;
  S->stacksize = STACK_INIF_SIZE;
  return OK;
}

GetTop

Status GetTop(SqStack S, SElemType *e)
{ // 若栈不空,用e返回S的栈顶元素
  if (S.top == S.base)
    return ERROR;
  (*e) = *(S.top - 1);
  return OK;
}

Push

Status Push(SqStack *S, SElemType e)
{ // 插入元素e为栈顶元素
  if (S->top - S->base >= S->stacksize)
  { // 栈满,追加储存空间
    S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
    if (!S->base)
      return ERROR;
    S->top = S->base + S->stacksize;
    S->stacksize += STACKINCREMENT;
  }
  *S->top++ = e;
  return OK;
}

Pop

Status Pop(SqStack *S, SElemType *e)
{ // 若栈不空,则删除S的栈顶元素,并用e返回其值
  if (S->top == S->base)
    return ERROR;
  (*e) = *--S->top;
  return OK;
}

测试

int main()
{
  SqStack *S = (SqStack *)malloc(sizeof(SqStack));
  InitStack(S);
  Push(S, 1);
  printf("%d %d\n", *S->base, *(S->top - 1));
  Push(S, 2);
  printf("%d %d\n", *S->base, *(S->top - 1));
  int *e = (int *)malloc(sizeof(int));
  Pop(S, e);
  printf("%d %d\n", *S->base, *(S->top - 1));
  printf("%d", *e);
  return 0;
}

链式存储结构

存储表示

链式存储便于多个栈共享存储空间以及提高其效率,且不存在栈满的情况,通常采用单链表实现,并规定所有操作都是在表头进行;这里没有头结点,直接指向栈顶元素,对于空栈即top == base = NULL;

//节点
typedef struct StackNode
{ 
  ElemType data;
  struct StackNode *next;
}StackNode, *LinkStackPrt;
//链栈
typedef struct LinkStack
{
  LinkStackPrt top;
  int count;
}LinkStack;

基本实现

Push

Status Push(LinkStack *S, ElemType e)
{ //插入新栈顶元素e
  //创建新节点
  LinkStackPrt p = (LinkStackPrt)malloc(sizeof(StackNode));
  p->data = e;
  p->next = S->top;
  S->top = p;
  S->count++;
  return OK;
}

Pop

Status Pop(LinkStack *S, ElemType *e)
{
  LinkStackPrt P;
  if(StackEmpty(*S))
    return ERROR;
  *e = S->top->data;
  p = S->top;
  S->top = S->top->next;
  free(p);
  S->count--;
  return OK;
}

栈的应用

表达式求值

波兰式(前缀表达式)

从左向右读入表达式,如果一个操作符后面跟着两个操作数时,将计算结果作为操作数替换这个操作符和两个操作数,直至计算完成;
such as 2 + 3 * (5 - 1),其波兰式为 + 2 * 3 - 5 1;

逆波兰式(后缀表达式)

相较于波兰式,逆波兰式要更为直接,当遇到操作符时,将前面两个操作数与这个操作符进行计算,结果替换;
如上的 2 + 3 * (5 - 1)用逆波兰式表示为 2 3 5 1 - * +;
这个过程很容易用栈来实现,将2, 3, 5, 1依次压入栈中,当压入 - 时,判定为操作符,Pop 5, 1,计算结果后再压入栈中,直至压入完成,栈中元素即运算结果;

中缀表达式转化为逆波兰式

由于计算机中广泛应用后缀表达式,因此中缀表达式转为后缀表达式很有必要;
从左向右遍历,遇到数字,输出到逆波兰式中;遇到符号,判断其与栈顶符号的优先级,是右括号或者优先级低于栈顶符号,则栈顶元素依次出栈并输出到逆波兰式中,并将当符号进栈,直至输出结束

如 2 + 3 * (5 - 1)则过程如下:

  • 2,输出到表达式中,2,栈为空;
  • +,到栈中,2,+;
  • 3,输出到表达式中,2 3,+;
  • *,到栈中,2 3,+ *;
  • (,到栈中,2 3,+ * (;
  • 5,表达式,2 3 5,+ * (;
  • -,栈中,2 3 5,+ * ( -;
  • 1,表达式,2 3 5 1,+ * ( -;
  • ),栈顶元素依次出栈并输出到表达式中,即2 3 5 1 - * +;

行编辑程序

在栈的功能下,实现用户在终端输入出现差错时,及时更正;

栈与递归的实现

……文章来源地址https://www.toymoban.com/news/detail-446161.html

到了这里,关于数据结构之栈的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构之栈、队列——算法与数据结构入门笔记(四)

    本文是算法与数据结构的学习笔记第四篇,将持续更新,欢迎小伙伴们阅读学习 。有不懂的或错误的地方,欢迎交流 栈是一种线性数据结构,其 只允许在固定的一端进行插入和删除 元素操作。进行数据插入和删除操作的一端称为栈顶 (Top), 另一端称为栈底 (Bottom)。栈中的

    2024年02月08日
    浏览(29)
  • 手撕数据结构之栈+例题

    目录 一、栈的概念及结构 二、栈的头文件及基本框架 三、接口实现 1、对栈的初始化  2、栈的销毁 3、入栈操作 4、出栈操作  5、判断栈是否为空 6、返回栈顶元素 7、遍历栈 四、有效的括号 - 力扣(LeetCode) 题目描述:  思路: 代码: 栈:一种特殊的线性表,其只允许

    2024年02月13日
    浏览(37)
  • 【数据结构】线性表之栈、队列

    前面两篇文章讲述了关于线性表中的顺序表与链表,这篇文章继续讲述线性表中的 栈和队列。 这里讲述的两种线性表与前面的线性表不同,只允许在一端入数据,一段出数据,详细内容请看下面的文章。 顺序表与链表两篇文章的链接: 线性表之顺序表 线性表之链表 注意:

    2024年02月06日
    浏览(41)
  • 数据结构之栈和队列

      数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法,为提高利用

    2024年01月22日
    浏览(35)
  • 《数据结构》之栈和堆结构及JVM简析

    在数据结构中,我们第一了解到了栈或堆栈,它的结构特点是什么呢?先进后出,它的特点有什么用呢?我们在哪里可以使用到栈结构,栈结构那么简单,使用这么久了为什么不用其它结构替代? 作为一个程序猿,我们应该会常常跟代码打交道,那么我们所编写的程序或代码

    2024年02月07日
    浏览(38)
  • 数据结构之栈与队列详解

    栈和队列是一种特殊的线性结构,他与之前学的线性结构不同,栈和队列是拥有一种特殊规则的线性结构,虽然它是用数组或者链表实现,但是只有符合这种规则才能被称作栈或者队列 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和

    2024年01月16日
    浏览(34)
  • 数据结构之栈的实现(附源码)

    目录 一、栈的概念及结构 ​二、栈的实现 三、初学栈的练习题 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插

    2024年02月07日
    浏览(36)
  • 数据结构奇妙旅程之栈和队列

    ꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶ 个人主页:xiaoxieʕ̯

    2024年02月04日
    浏览(33)
  • 数据结构之栈的基本操作

    该顺序栈涉及到了存储整型数据的顺序栈还有存储字符型数据的顺序栈 实现的功能有:入栈、出栈、判断是否为空栈、求栈的长度、清空栈、销毁栈、得到栈顶元素 此外根据上述功能,编写了数值转换(十进制转化八进制)方法、括号匹配方法。 控制台界面展示: 进栈展示

    2024年01月23日
    浏览(41)
  • 数据结构之栈和队列---c++

    栈 栈是一个“先进后出”结构 队列 入队演示 队列是一种“先进先出”的结构 出队演示 接下来我们开始本次的内容 分析 1.我们可以 老老实实的写一个栈 然后将所有的接口函数实现出来,最后再进行实现队列,但是显然是 效率低下 的方法 2.我们使用 数组模拟栈 ,然后再进

    2024年02月14日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包