数据结构--线性结构(三)--堆栈

引入:后缀表达式求值

后缀表达式:运算符号位于两个运算数之后

例:62/3-42*+ = 8

求值策略:从左向右“扫描”,逐个处理运算数和运算符号

  1. 遇到运算数:记住当前运算数
  2. 遇到运算符:运用对应的运算数进行计算,将计算得到的数记住
  • 需要有种存储方法,能顺序存储运算数, 并在需要时“倒序”输出!

一、堆栈的抽象数据类型描述

堆栈(Stack):具有一定操作约束的线性表 ,即只在一端(栈顶,Top)做 插入、删除(后入先出

 二、栈的顺序存储实现

1.定义:栈的顺序存储结构通常由一个一维数组和一个记录 栈顶元素位置的变量组成。

#define MaxSize <储存数据元素的最大个数>
typedef struct SNode *Stack;
struct SNode{
ElementType Data[MaxSize];
int Top;
};

2.操作:

1)入栈

void Push( Stack PtrS, ElementType item )
{
 if ( PtrS->Top == MaxSize-1 ) {
 printf(“堆栈满”); return;
 }else {
 PtrS->Data[++(PtrS->Top)] = item;
 return;
 }
}

2)出栈

ElementType Pop( Stack PtrS )
{
 if ( PtrS->Top == -1 ) {
 printf(“堆栈空”);
 return ERROR; /* ERROR是ElementType的特殊值,标志错误
*/
 } else
 return ( PtrS->Data[(PtrS->Top)--] );
}

三、栈的链式存储实现

单链表结构表示,为链栈。插入和删除操作只能在链栈的栈顶进行,头结点为栈顶。

1定义:

typedef struct SNode *Stack;
struct SNode{
ElementType Data;
struct SNode *Next;
} ; 

2操作:

1)入栈:

void Push( ElementType item, Stack S)
{ /* 将元素item压入堆栈S */
struct SNode *TmpCell;
TmpCell=(struct SNode *)malloc(sizeof(struct SNode));
TmpCell->Element = item;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}

2)出栈:

ElementType Pop(Stack S)
{ /* 删除并返回堆栈S的栈顶元素 */
 struct SNode *FirstCell;
ElementType TopElem;
if( IsEmpty( S ) ) {
printf(“堆栈空”); return NULL;
} else {
FirstCell = S->Next;
S->Next = FirstCell->Next;
TopElem = FirstCell ->Element;
free(FirstCell);
return TopElem;
}
}

四、应用

1.后缀表达式求值:

步骤:

  1. 运算数:入栈;
  2. 运算符:从堆栈中弹出适当数量的运算数,计算并结果入栈;
  3. 最后,堆栈顶上的元素就是表达式的结果值。

2.中缀表达式求值:

基本策略:将中缀表达式转换为后缀表达式,然后求值。

中缀表达式转化为后缀表达式:

从头到尾读取中缀表达式的每个对象,对不同对象按不同的情况处理。

① 运算数:直接输出;

② 左括号:压入堆栈;

③ 右括号:将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出);

④ 运算符:

       • 若优先级大于栈顶运算符时,则把它压栈;

       • 若优先级小于等于栈顶运算符时,将栈顶运算符弹出并输出;再比 较新的栈顶运算符,直到该运算符大于栈顶运算符优先级为止,然 后将该运算符压栈;

⑤ 若各对象处理完毕,则把堆栈中存留的运算符一并输出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值