第三章栈和队列

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、数制转换 二、 括号匹配 三、 行编辑 四、迷宫求解 五、 表达式求值
一、数制转换
对于输入的任意一个非负十进制整数 打印输出与其等值的八进制数
4107 513 64
3余

1数 产
0生
进 制 输 出
8
0顺

1


1
0
void conversion ( )
{ InitStack(S);
∥建空栈
scanf(&N);
a+b*(c+d)+(c-d)/f
栈 内
+-*/() #
+>><<<>>
->><<<>>
*>>>><>>
/>>>><>>
(<<<<<=
)>>>>
>>
#<<<<<
=
操作数
(1) 初始化,置OPND为空栈,
将‘#’压入OPTR栈底
运算符
(2) 依次读入表达式中的每个成员:
(a)若是操作数,压入OPND栈
如果栈空,表明右括号多了 否则与栈顶元素比较,若相匹配,左括号出栈
否则不匹配 (3)表达式检查结束时,若栈空,则匹配正确
Status match( ) {InitStack(S); scanf(ch);
while (ch!= '\n') { if (ch== '( ' || ch== '[ ' ) Push(S,ch);
int StackLength(SqStack S);
∥返回S的元素个数,即栈的长度
Status GetTop(SqStack S, SElemType &e);
∥若栈不空,则用e返回S的栈顶元素,并返回OK; 否则返回ERROR
Status Push(SqStack &S, SElemType e);
Pass(curpos)
//返回位置curpos是否可通(搜索过)
NextPos(curpos,i); //返回从位置curpos按方向i到达的新位置
MarkPrint(curpos); //记录位置curpos4个方向都搜索过不可通
Status MazePath (MazeType maze, PosType start,
Status InitStack(SqStack &S);
∥构造一个空栈S
Status DestroyStack(SqStack &S);
∥销毁栈S,S不在存在
Status ClearStack(SqStack &S);
∥把S置为空栈
Status StackEmpty(SqStack S);
∥若栈S为空栈,则返回TRUE,否则返回FALSE
if (S.top ==S.base) return ERROR; e = *(S.top-1); return OK; }∥GetTop
top
e
base
Status Push (SqStack &S,SElemType e)
{ ∥插入元素e为新的栈顶元素
if(S.top-S.base>=S.stacksize)
{ int x,y;
}PosType; ∥坐标
typedef struct
{ int
ord;
∥通道块在路径上的"序号"
PosType seat; ∥通道块在迷宫中的"坐标位置"
int
di;
∥从此通道块走向下一通道块的"方向"
}SElemType;
∥栈的元素类型
FootPrint(curpos); //记录位置curpos已经搜索过
{ ∥当前位置可以通过,即是未曾走到过的通道块
FootPrint(curpos);
∥留下足迹
e = (curstep,curpos,1);
Push(S,e);
∥加入路径
if(curpos==end) return(TRUE);
∥到达终点(出口)
curpos = NextPos(curpos,1); 一位置是当前位置的东邻
StackLength(S);
操作结果:返回S的元素个数
GetTop(S, &e); 初始条件:栈S已存在且非空. 操作结果:用e返回S的栈顶元素.
Pop(&S, &e);
初始条件:栈S已存在且非空. 操作结果:删除S的栈顶元素,并用e返回其值
Push(&S, e);
操作结果:插入元素e为新的栈顶元素.
//设OPTR和OPND分别为运算符栈和运算数栈
InitStack(OPTR); Push(OPTR,'#'); InitStack(OPND); c = getchar( ); while(c!='#'‖GetTop(OPTR)!='#') { if (!In(c,OP)) {Push((OPND,c);c = getchar( ); }
∥存储分配失败
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}∥InitStack
100
top base
Status GetTop(SqStack S, SElemType &e) {∥若栈不空,则用e返回S的栈顶元素,并返回OK;
∥否则返回ERROR
则{ 将当前位置入栈;
∥纳入路径
若该位置是出口位置,则结束; ∥求得路径存放在栈中
否则切换当前位置的东邻方块为新的当前位置;
}
否则
若栈不空
{ 出栈e 若e的四周均不可通(或探索过)则继续出栈 若e尚有其他方向未经探索 沿顺时针方向找到新的当前位置
}
}while(栈不空)
typedef struct
{ e.di++; Push (S,e);
∥换下一个方向探索
curpHale Waihona Puke Baidus = NextPos(e.seat, e.di);
}∥if }∥if }∥if(else)
∥设定当前位置是该新方向上的相邻块
}while(!StackEmpty(S));
return(FALSE); }∥MazePath
四、表达式求值
∥ –––––基本操作的算法描述(部分)–––––
Status InitStack(SqStack &S)
{ ∥构造一个空栈S
S.base=(SElemType*) malloc(STACK_INIT_SIZE
*sizeof(SElemType));
if (!S.base) exit(OVERFLOW);
scanf(ch); } if(StackEmpty(S) return OK; else return ERROR; }//match
三、迷宫求解
墙 通道 入口 出口
墙 通道 入口 出口
算法思想: 若当前位置可通,则加入路径 若当前位置不可通,则后退,换一个方向搜索 若四周都不可通,则从路径中删除
else if (ch== ')') { if(StackEmpty(S)) return ERROR; Pop(S, t); if (t!= '(' ) return ERROR; }
else if (ch== ' ] ') {if(StackEmpty(S)) return ERROR; Pop(S, t); if (t!= '[' ) return ERROR; }
第三章栈和队列
3.1 栈 3.2 栈的应用 3.3 栈与递归的实现 3.4 队列
出站
入站 火车站
•栈的抽象数据类型
ADT Stack {数据对象:D ={a i∣a i ∈ElemSet, i= 1,2,…,n, n≥0} 数据关系: R = {< a i-1 , a i > ∣ a i-1 , a i ∈D, i = 2,…,n }
StackEmpty(S); StackLength(S);
GetTop(S, &e);
StackTraverse(S, visit( ));
Push(&S, e); Pop(&S, &e);
二、栈的表示和实现
1.顺序栈
利用一组地址连续的空间存放栈底到栈顶的元素 用指针top指出栈顶元素的位置
2.顺序栈定义 typedef struct { SElemType *base;
路径中最先被删除的位置是最近搜索过的 利用栈存放路径
设定当前位置的初值为入口位置; do{
若当前位置可通, { 将当前位置入栈; 切换当前位置的东邻方块为新的当前位置; }
若当前位置不可通, {出栈 找到下一个可能通的位置
} }while(栈不空)
设定当前位置的初值为入口位置;
do{
若当前位置可通,
(b)若是界限符或运算符,
则与OPTR栈内运算符比较优先级,
若栈内高,
则从OPTR弹出运算符,
并OPND从弹出相应个数的操作数进行运算,
将运算结果压入OPND栈
否则,将读入的运算符压入OPTR栈
(3) 重复(2),直到读入‘#’且栈顶为‘#’为止
OperandType EvaluateExpression( ) { ∥算术表达式求值的算符优先算法, OP为运算符集合
约定a n端为栈顶, a 1端为栈底. 基本操作:
InitStack(&S); 操作结果:构造一个空栈S.
DestroyStack(&S);
操作结果:栈S被销毁
ClearStack(&S); 操作结果:栈S清为空栈.
StackEmpty(S);
操作结果:若栈S为空栈,则返回TRUE, 否则FALSE
S.stacksize +=STACKINCREMENT;
}
*S.top++ = e;
top
return OK;
top
e
e
}∥Push
base
Status Pop(SqStack &S,SElemType &e)
{ ∥若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR;
if(S.top==S.base) return ERROR;
{ ∥栈满,追加存储空间
S.base = (SElemType*)realloc(S.base, (S.stacksize+
STACKINCREMENT)*sizeof(SElemType));
if(!S.base)exit(OVERFLOW);
∥存储分配失败
S.top = S.base + S.stacksize;
PosType end)
{ ∥若迷宫maze中存在从入口start到出口end的通道,则求得一条存放在栈中
∥(从栈底到栈顶),并返回TRUE;否则返回FALSE
InitStack(S); curpos = start; ∥设定"当前位置"为"入口位置"
curstep = 1;
∥探索第一步
do
{ if(Pass(curpos))
SElemType *top; int stacksize; }SqStack;
3·顺序栈的实现
∥ –––––栈的顺序存储表示 ––––– #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10
∥存储空间初始分配 ∥存储空间分配增量
∥––––– 基本操作的函数原型说明 –––––
∥插入元素e为新的栈顶元素
Status Pop(SqStack &S, SElemType &e);
∥若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK; ∥ 否则返回ERROR
Status StackTraverse(SqStack S, Status(*visit)());
∥从栈底到栈顶依次对栈中每个元素调用函数visit(). ∥一旦visit()失败,则操作失败.
curstep ++; }
∥探索下一步
else //if(!Pass(curpos))
{ ∥当前位置不能通过
if(!StackEmpty(S))
{ Pop(S,e);
while (e.di==4&&!StackEmpty(S))
{MarkPrint(e.seat); Pop(S,e)}//留下不能通过的标记,并退回一步 if(e.di<4)
while(N)
{ Push(S, N%8); N = N/8; }
while(!StatckEmpty(S))
{ Pop(S,e); printf("%d",e); }
}∥conversion
二、 括号匹配
输入一个符号串,判断其中圆括号和方括号是否匹配
(ab[hj](f[h(j)k]gh))
算法思想: (1)凡出现左括号,则进栈 (2)凡出现右括号,首先检查栈是否空
StackTraverse(S, visit( ));
初始条件:栈S已存在且非空. 操作结果:从栈底到栈顶依次对S的每个数据元素调用函数visit().
一旦visit()失败, 则操作失效.
}ADT Stack
InitStack(&S);
DestroyStack(&S);
ClearStack(&S);
e = * --S.top;
return OK; }∥Pop
top
top
e
base
4.栈式链 *top为首元结点,做栈顶 链式栈是在表头进行插入删除操作的链
top
a5
a4
a3
a2 a1
头结点?
三、 多个栈共享空间 1.两个栈共享空间
base1
top1
2.多个栈共享空间
top2
base2
3.2栈的应用
相关文档
最新文档