首页 > 其他分享 >数据结构之栈

数据结构之栈

时间:2023-05-16 17:11:56浏览次数:43  
标签:SElemType return top 之栈 栈顶 base 数据结构 表达式

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 - * +;

行编辑程序

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

栈与递归的实现

……

标签:SElemType,return,top,之栈,栈顶,base,数据结构,表达式
From: https://www.cnblogs.com/houchaoqun/p/17350223.html

相关文章

  • Redis数据结构二之SDS和双向链表
    本文首发于公众号:Hunter后端原文链接:Redis数据结构二之SDS和双向链表这一篇笔记介绍一下SDS(simpledynamicstring)和双向链表。以下是本篇笔记目录:SDS常数复杂度获取字符串长度杜绝缓冲区溢出减少修改字符串带来的内存重分配次数二进制安全兼容C字符串函数双向链......
  • 架构师日记-从数据库发展历程到数据结构设计探析
    作者:京东零售刘慧卿一数据库发展史起初,数据的管理方式是文件系统,数据存储在文件中,数据管理和维护都由程序员完成。后来发展出树形结构和网状结构的数据库,但都存在着难以扩展和维护的问题。直到七十年代,关系数据库理论的提出,以表格形式组织数据,数据之间存在关联关系,具有了良好......
  • Redis数据结构一之对象的介绍及各版本对应实现
    本文首发于公众号:Hunter后端原文链接:Redis数据结构一之对象的介绍及各版本对应实现本篇笔记开始介绍Redis数据结构的底层实现。当我们被问到Redis中有什么数据结构,或者说数据类型,我们可能会说有字符串、列表、哈希、集合、有序集合。其实这几种数据类型在Redis中都由......
  • 数据结构与算法之一道题感受算法(算法入门)
    题目:给定N个整数的序列{A1,A2,....An},求函数F(i,j)=Max{Ai+.....Aj }题目要求:这道题的目的是要求给定的一个整数序列中,它所含的连续子序列的最大值,比如现在我有一个整数序列{-3,2,3,-3,1}它的最大子序列很显然是 {2,3}第一种方法蛮力法(强制枚举):我们从第一个整数开始遍历,依......
  • 个人推荐讲的非常好的数据结构免费[速成 速成 速成]视频了
    适用人群期末突击,二级+期末+考研+学习数据结构打基础,考前复习数据结构,巩固数据结构基础学习步骤:每一章,都会先讲基础,然后下一节就是配套习题讲解,坚持学完全部章即可拿捏期末,同时在课程最后提供一个新的整套题的讲解,进行巩固拔高好评截图:  几个小时就带你过了一边基础,讲了直......
  • 数据结构-二维数组内存结构
    二维数组内存结构  逻辑上是二维的,再分配内存的时候,也是给他分配一维的内存行优先存储 行优先存储,M行N列的b[i][j]的存储地址=基地址+(i*N+j)*sizeof(ElemType)列优先存储 M行N列b[i][j]的存储地址=基地址+(j*M+i)*sizeof(ElemType)......
  • chapter2-R的数据结构
    chapter2-R的数据结构R语言的数据结构分为5种类型:标量,向量,矩阵,列表,数据框向量-c()c()构建成的仅包含数值型、字符型、逻辑型数据的一维数组a<-c(1,2,3,4,5) ###数值型的向量b<-c('one','two','three')  ###字符型数据c<-c(T,F) ##逻辑型数据向量中元素的......
  • 数据结构教程之树
    树大家都见过吧当然,我们今天说的不是这个树,而是这个这玩意和大自然中的树有啥关系呢很简单首先,做一个树的简笔画然后,在每条树枝的起点和终点画上圆圈,树枝交会的地方也要画其次,在圆圈间树枝的地方用直线连接随后,把原来的简笔画去掉,整理一下圆圈,凑得太紧的分开一点,太远......
  • 【LeetCode数据结构04】字符串String
    TableofContents双指针344.反转字符串541.反转字符串II剑指Offer05.替换空格151.翻转字符串里的单词剑指Offer58-II.左旋转字符串KMP28.实现strStr459.重复的子字符串Solutions344.反转字符串力扣题目链接思路代码541.反转字符串II......
  • go语言调度gmp数据结构
    go语言调度gmp数据结构g表示goroutine,它是待执行的任务m表示操作系统的线程,它由操作系统的调度器调度和管理p表示处理器,可以把它看作在线程上运行的本地调度器Ggoroutine是go语言调度器中待执行的任务,它在运行时调度器中的地位和线程在操作系统中的地位差不多,但是它占......