当前位置:
文档之家› 数据结构详细讲解(栈和队列)
数据结构详细讲解(栈和队列)
}
链栈的出栈操作
int Pop(LinkStack top, ElemType *x) { temp=top->next; if(temp==NULL) return FALSE; /*栈为空*/ top->next=temp->next; *x=temp->data; free(temp); /* 释放存储空间 */ return TRUE;
共享栈的空间示意
top[0]和top[1]分别为两个栈顶指示器
Stack:0
M-1
top[0]
top[1]
两栈共享的数据结构定义
#define M 100
typedef struct {
ElemType Stack[M]; int top[2]; } DqStack;
两栈共享的初始化
void InitStack ( DqStack *S ) {
链栈的入栈操作
int Push(LinkStack top, ElemType x) { temp=( )malloc(sizeof(LinkStackNode)); if(!temp) return FALSE; temp->data=x; temp->next=top->next; top->next=temp; /* 修改当前栈顶指针 */ return TRUE;
若表达式未输入完,转1
后缀表达式求值
例: 计算 4+3*5
后缀表达式:435*+
5
3
3
15
4
4
4
4
19
栈的应用5—函数的调用
函数的嵌套调用
主 程 序
子 过 程 ss
子
t s
过 程
t
f t s
子 过 程
fLeabharlann tssf t s
栈的应用5—函数的调用
函数的递归调用(函数直接或间接的调用自身)
例:
void print(int w) { int i;
答案: 1002H
顺序栈的基本操作
顺序栈的初始化操作 顺序栈的判空操作 顺序栈的判满操作 顺序栈的插入操作(入栈) 顺序栈的删除操作(出栈) 顺序栈的读取栈顶元素操作
顺序栈的初始化
void InitStack ( SeqStack * s ) {
S->top= -1; }
顺序栈的判空
S->top[0]=-1; S->top[1]=M; }
两栈共享的入栈操作
int Push(DqStack *S, ElemType x, int i) { if(S->top[0]+1==S->top[1]) return(FALSE);
switch(i) { case 0: S->top[0]++; S->Stack[S->top[0]]=x; break;
(1) 栈的定义和特点 (2) 栈的抽象数据类型定义 (3) 栈的表示和实现 (4) 栈的应用
栈的定义
定义:限定仅在表尾进行插入或删除操作 的线性表。
表尾—栈顶 表头—栈底 不含元素的空表称空栈
栈的特点
特点:先进后出(FILO)或后进先出(LIFO)
进栈
栈顶
an
a2
栈底
a1
……...
if ( S->top== -1 ) return FALSE; *e=S->elem[S->top]; S->top--; return TRUE; }
顺序栈中读取栈顶元素
int GetTop ( SeqStack *s, ElemType *e ) {
if ( S->top== -1 ) return FALSE; *e=S->elem[S->top]; return TRUE; }
{ x=N%2; Push(&S, x); N=N/2; }
while(!IsEmpty(S))
{ Pop(&S,&x); printf(“%d”,x); }
}
十进制数转换成K进制数
void Conversion(int N,int base)
{ Stack S; int x;
/*S为顺序栈或链栈*/
}
顺序栈的入栈
int Push ( SeqStack *S, ElemType e ) {
if(S->top==Stack_Size-1) return FALSE; S->top++; S->elem[S->top]=e; return TRUE; }
顺序栈的出栈
int Pop ( SeqStack *S, ElemType *e ) {
操作数栈和运算符栈
例 计算 2+4-3*6
4
2
+
操作数 运算符
6
-
操作数 运算符
6 3 6 操作数
* 运算符
18
6
-
操作数 运算符
-12 操作数 运算符
后缀表达式求值
后缀表达式求值步骤(引入一个栈即可): 1.读入表达式一个字符 2.若是操作数,压入栈,转4 3.若是运算符,从栈中弹出2个数,将运算 结果再压入栈 4.若表达式输入完毕,栈顶即表达式值;
int IsEmpty ( SeqStack * s ) {
if ( S->top= =-1 ) return 1;
else return 0;
}
顺序栈的判满
int IsFull ( SeqStack * s ) {
if ( S->top = = Stack_Size-1 ) return 1;
else return 0;
栈的表示和实现
栈在计算机中主要有两种基本的存储结构: 顺序存储结构和链式存储结构。
顺序存储的栈称为顺序栈 链式存储的栈称为链栈
顺序栈
顺序栈:利用一组地址连续的存储单元依次存 放自栈底到栈顶的数据元素,同时附设指针 top指示栈顶元素在顺序栈中的位置。
顺序栈的类型说明: typedef struct { ElemType elem[Stack_Size]; int top; }SeqStack;
第三章 栈和队列
栈和队列
栈和队列是两种特殊的线性表 是操作受限的线性表,称为限定性的数据结构 栈的插入和删除限定在表尾 队列的插入限定在表尾,删除限定在表头
第3章 栈和队列
3.1 栈(Stack) 3.2 队列(Queue) 3.3 本章小结 3.4 课后练习
3.1 栈(Stack)
F5
top
E4
top D3
top
C2
top
B1
top
A0
top
出栈
栈空时出栈,则下溢(underflow) 栈满时入栈,则上溢(overflow)
思考题
设有一个空栈,栈的首地址为1000H(十六进制), 经过push,push,pop,push,pop,push,pop,push后,栈 顶元素的地址为多少(sizeof(ElemType)=2)?
顺序栈的top指针
top==-1,表示栈空; top== stacksize-1,表示栈满; 每插入一元素时,top加1; 每删除一元素时,top减1;
顺序栈的操作过程示意
栈满
栈空
5 top
F5
4 top
E4
3 top
D3
2 top 1 top
C2 B1
0 top
A0
top
空栈
进栈
top
...
出栈 栈s=(a1,a2,……,an)
入栈序列与出栈序列
栈具有LIFO性质,若已知栈的输入序列为1 2 3, 则输出序列有多少种呢?
以1为头:123 132 以2为头:213 231 以3为头:321
入栈序列与出栈序列
若已知栈的输入序列为1 2 3 4,则输出序列有多 少种呢?
以1为头:1234 1243 1324 1342 1432 以2为头:2134 2143 2314 2341 2431 以3为头:3214 3241 3421 以4为头:4321 当输入序列为1 2 … n时,经过栈可获得的输出 序列的个数由尤.卡塔南数决定,即:
InitStack(&S);
while(N)
{ x=N%base; Push(&S, x); N=N/base; }
while(!IsEmpty(S))
{ Pop(&S,&x);
if(x<10) printf(“%d”,x);
else printf(“%c”,x+55); }
}
栈的应用2 — 括号匹配检验
两栈共享技术
若在一个程序中要同时使用多个栈,如果采用 顺序存储结构
会因为栈空间大小难以准确估计,产生有的栈 溢出,有的栈还很空闲的情况
解决措施:两栈共享技术
两栈共享技术
主要利用了栈“栈底位置不变,而栈顶位置动 态变化”的特性。
首先为两个栈申请一个共享的一段存储空间 S[M]
然后将两个栈的栈底分别放在存储空间的两端 ,分别是0,M-1。
{ case 0: if(S->top[0]==-1) return(FALSE); *x=S->Stack[S->top[0]]; S->top[0]--; break;
case 1: if(S->top[1]==M) return(FALSE); *x=S->Stack[S->top[1]]; S->top[1]++; break;