目录
3.1 栈和队列的定义和特点
3.1.1栈的定义和特点
3.1.2 队列的定义和特点
3.2 栈的表示和操作的实现
3.2.1栈的类型定义
3.2.2 顺序栈的表示和实现
顺序栈的存储结构定义:
初始化:
入栈:
出栈:
取栈顶元素:
遍历栈中元素:
获取栈中元素个数:
判断栈是否为空:
3.2.3 链栈的表示和实现
链栈的存储结构定义:
初始化:
入栈:
出栈:
取栈顶元素:
遍历栈中元素:
获取栈中元素个数:
判断链栈是否为空:
3.2.4 栈的应用----括号的匹配检测
3.2.5 栈的相关考研真题:
3.3 队列的表示和操作的实现
3.3.1 队列的类型定义
3.3.2 循环队列----队列的顺序表示和实现
队列的存储结构:
初始化:
入队:
出队:
取队头元素:
求循环队列的长度:
判断队列是否为空:
遍历队列中元素:
3.3.3 队列的相关考研真题
栈是限定仅在表尾进行插入或删除的线性表。因此,对栈来说,表尾端有特殊含义,称为栈顶,相应地,表头端称为栈底。不含元素的空表称为空栈。
栈又称为后进先出的线性表,形象地看成是一个无盖的铁桶,大家脑补一下。
队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素,大家可以想象一下我们生活中的排队。
在队列中,允许插入的一端称为队尾,允许删除的一端称为队头。
1.InitStack(&S) 构造一个空栈S
2.Push(&S,e) 元素入栈操作
3. Pop(&S,&e) 元素出栈操作
4.GetTop(S) 取栈顶元素
5.StackLength(S) 统计栈中元素的个数
6.StackTraverse(S) 遍历栈中元素
7.StackEmpty(S) 判断栈是否为空
顺序栈是利用顺序存储结构实现的栈,即利用一组地址连的存储单元依次存放自栈底到栈顶的数据元素。
typedef struct{
SElemType *top,*base;//定义栈顶和栈底指针
int stacksize;//定义栈的容量
}SqStack;
Status InitStack(SqStack &S){//初始化一个空栈
S.base=new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的空间
if(S.base==NULL) return ERROR;//判断存储是否分配成功
S.top=S.base;//将top初始化为base,置为空栈
S.stacksize=MAXSIZE;//stacksize置为最大容量MAXSIZE
return OK;
}
Status Push(SqStack &S,SElemType e){//入栈
if(S.top-S.base==S.stacksize) return ERROR;//判断是否栈满
*S.top=e;
S.top++;
return OK;
}
Status Pop(SqStack &S,SElemType &e){//出栈
if(S.top==S.base) return ERROR;//判断栈是否为空
S.top--;
e=*S.top;
return OK;
}
SElemType GetTop(SqStack S){//获取栈顶元素
if(S.top!=S.base)
return *(S.top-1);
}
Status PrintfStack(SqStack S){//遍历栈内的所有元素
SElemType *p;
p=S.base;
printf("栈中的元素为:");
while(p!=S.top){
printf("%d ",*p);
p++;
}
printf("\n");
}
int StackLength(SqStack S){//获取栈的长度
int len=0;
SElemType *s;
s=S.base;
while(s!=S.top){
len++;
s++;
}
printf("栈的长度为:%d\n",len);
}
Status StackEmpty(SqStack S){//判断栈是否为空
if(S.top==S.base) return ERROR;
else
return OK;
}
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
Status InitStack(LinkStack &S){//链式栈的初始化
S=NULL;
return OK;
}
Status Push(LinkStack &S,SElemType e){//元素入栈
StackNode *p;
p=new StackNode;
p->data=e;
p->next=S;
S=p;
return OK;
}
Status Pop(LinkStack &S,SElemType &e){//元素出栈
if(S==NULL) return ERROR;
e=S->data;
StackNode *p;
p=S;
S=S->next;
delete p;
return OK;
}
Status GetTop(LinkStack S){//获取栈顶元素
if(S!=NULL) return S->data;
}
Status printfStack(LinkStack S){//遍历链式栈中的元素
StackNode *p;
p=S;
printf("链式栈中的元素为:");
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
int StackLength(LinkStack S){//获取栈的长度
StackNode *p;
p=S;
int count=0;
while(p!=NULL){
count++;
p=p->next;
}
printf("栈的长度为:%d\n",count);
}
Status StackEmpty(LinkStack S){//判断链式栈是否为空
if(S==NULL) return ERROR;
return OK;
}
案例:
[[]](){} 匹配
[[]](} 不匹配
直接上代码: (此案例只适用于[],(),{}三种括号,如要增加其余括号,在程序中修改即可)
#include
#include
using namespace std;
typedef struct
{
char *base;//定义栈底指针
char *top;//定义栈顶指针
int stacksize;
}SqStack;
int InitStack(SqStack &S)//初始化
{
S.base=new char[100];
if(S.base==NULL) return 0;
S.top=S.base;//此处很重要,位置不能互换
S.stacksize=100;
return 1;
}
int Push(SqStack &S,char e)//入栈
{
if(S.top-S.base==S.stacksize) return 0;
*S.top++=e;
return 1;
}
int Pop(SqStack &S,char &e)//出栈
{
if(S.base==S.top) return 0;
e=*--S.top;
return 1;
}
char GetTop(SqStack S)//取栈顶元素
{
if(S.base!=S.top)
return *(S.top-1);
}
int Match(SqStack &S,char str[])
{
int flag=1;
int len=strlen(str);
for(int i=0;i
案例测试:
测试案例一:
[[]](){}
运行结果:
测试案例二:
[[]](}
运行结果:
1.给定有限符号集S,in和out均为S中所有元素的任意排列。对于初始为空的栈ST,下
列叙述中,正确的是( ) 。 【全国联考2022年】
A若i是ST的人栈序列,则不能判断out是否为其可能的出栈序列
B若out是ST的出栈序列,则不能判断in是否为其可能的入栈序列
C.若in是ST的入栈序列,out是对应in的出栈序列,则i与out一定不同
D.若in是ST的入栈序列,out 是对应in的出栈序列,则in与out可能互为倒序
答案:D
解析:根据栈的特性可以根据入栈序列,可以推出可能的出栈序列。同样,根据出栈序列,可以推出可能的入栈序列。若元素进栈即出栈,则入栈序列和出栈序列相同。若元素依次进栈完后,再依次出栈,则入栈序列和出栈序列互为倒序。由此,A,B,C错误,D选项正确。
2.对空栈S进行Push和Pop操作,人栈序列为a,b,c,d,e,经过Push,Push,Pop,Push Pop,Push,Push,Pop操作后,得到的出栈序列是( )。 【全国联考2020年】
A.b,a,c B.b,a,e C.b,c,a D.b,c,e
答案:D
解析:栈是一种后进先出的数据结构,Push 和Pop操作分别为入栈和出栈操作。如题所述的操作过程:a入栈,b入栈,b出栈,c人栈,c出栈,d入栈,e入栈,e出栈。因此,得到的出栈序列是b,c,e。
3.若栈S中保存整数,栈S2中保存运算符,函数F()依次执行下述各步操作:
(1)从S1中依次弹出两个操作数a和b
(2)从S2中弹出一个运算符op(3)执行相应的运算b op a
(4)将运算结果压入S1中
假定S1中的操作数依次是5,8,3,2(2在栈顶),S2中的运算符依次是*,-,+(+在栈顶)。
调用3次F()后,S1栈顶保存的值是( )。 【全国联考2018年】
A.-15 B.15 C.-20 D.20
答案:B
解析:第一次调用F():2和3依次出栈,+出栈,a=2,b=3,op=+,b op a=3+2=5,将5压
入S1中。
第二次调用F():5和8依次出栈,-出栈,a=5,b=8,op=-,b op a=8-5=3,将3压入
S1中。
第三次调用F():3和5依次出栈,*出栈,a=3,b=5,op=*,b op a=5*3=15,将15压入
S1中。
综上所述,调用3次F()后,S栈顶保存的值是15。
4.下列关于栈的叙述中,错误的是( )。【全国联考2017】
I.采用非递归方式重写递归程序时必须使用栈Ⅱ.函数调用时,系统要用栈保存必要的信息
Ⅲ只要确定了入栈次序,即可确定出栈次序
Ⅳ栈是一种受限的线性表,允许在其两端进行操作
A.仅I B.仅I、Ⅱ、Ⅲ C.仅I、Ⅲ、Ⅳ D.仅Ⅱ,Ⅲ,Ⅳ
答案:C
解析:采用非递归方式重写递归程序时,不一定使用栈,如计算斐波那契数列迭代实现只需要一个循环即可;确定了入栈次序也无法确定出栈次序,因为出栈的时机无法确定;栈是一一种受限的线性表,只允许在其一端进行操作。(栈顶进行操作)
1.InitQuese(&Q) 构造一个空的队列
2. EnQuese(&Q) 元素入队
3. DeQuese(&Q,&e) 元素出队
4.GetHead(Q) 取队头元素
5.QueseLength(Q) 求循环队列的长度
6.QueseEmpty(Q) 判断队列是否为空
7.QueseTraverse(Q) 遍历队列中的元素
typedef struct{
QElemType *base;//存储空间的基地址
int front;//头指针
int rear;//尾指针
}SqQuese;
Status InitQuese(SqQuese &Q){//队列的初始化
Q.base=new QElemType[MAXQSIZE];//为队列分配一个最大容量MAXSIZE的存储空间
if(Q.base==NULL) return ERROR;
Q.front=Q.rear=0;//将队列的头指针和尾指针置为0,队列为空
return OK;
}
Status EnQuese(SqQuese &Q,QElemType e){//入队
if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR;//判断队列是否满
Q.base[Q.rear]=e;入队,新元素插入队尾
Q.rear=(Q.rear+1)%MAXQSIZE;//队尾指针加1
return OK;
}
Status DeQuese(SqQuese &Q,QElemType &e){//出队
if(Q.rear==Q.front) return ERROR;//判断队列是否为空
e=Q.base[Q.front];//保存队头元素
Q.front=(Q.front+1)%MAXQSIZE;//队头指针加1
return OK;
}
QElemType GetHerd(SqQuese Q){//获取队头元素
if(Q.front==Q.rear) return ERROR;//判断队列是否为空
return Q.base[Q.front];//返回队头元素
}
QElemType GetHerd(SqQuese Q){//获取队头元素
if(Q.front==Q.rear) return ERROR;
return Q.base[Q.front];
}
Status QueseEmpty(SqQuese Q){//判断队是否为空
if(Q.front==Q.rear) return ERROR;
return OK;
}
Status QueseTraverse(SqQuese Q){//遍历队列中的所有元素
if(Q.front==Q.rear) printf("队列为空!\n");
else{
printf("队的元素为:");
while(Q.front!=Q.rear){
printf("%d ",Q.base[Q.front]);
Q.front++;
}
printf("\n");
}
}
1.已知初始为空的队列Q的一端仅能进行入队操作,另外一端既能进行入队操作又能进行出队操作。若Q的入队序列是1,2,3,4,5,则不能得到的出队序列是( )。 【全国联考2021】
A.5,4,3,1,2 B.5,3,1,2,4 C.4,2,1,3,5 D.4,1,3,2,5
答案:D
解析:这个队列两边都可以进行出队,但只有一端能够进行入队,并且入队的序列已经告诉我们了,按照要求,只有D不符合入队要求,无法得到对应的出队序列。
2.循环队列存放在一维数组A[0…M-L1中,end1指向队头元素,end2指向队尾元素的后一个位置。假设队列两端均可进行入队和出队操作,队列中最多能容纳M-1个元素,初始时为空。下列判断队空和队满的条件中,正确的是( )。【全国联考2014年】
A.队空:end1==end2 队满:endl==(end2+1) mod M
B.队空:endl==end2 队满:end2==(end1+1) mod(M-1)
C.队空:end2==(end1+1) mod M 队满:endl==(end2+1) mod M
D.队空:endl==(end2+1) mod M 队满:end2==(end1+1) mod (M-1)
答案:A
解析:按照队列的相关操作只有A选项符合题意。
我今天刷到了一个关于丘吉尔的电影中的演讲片段,很振奋人心,在面对德军的入侵,这位刚刚上任了20天的首相用一段激情四射的演讲打动了所有人的内心,有一句话很好,在这里分享给大家,“成功不是终点,失败也并非末日,最重要的是继续前进的勇气。”,请大家记住这位优秀的首相------温斯顿.丘吉尔。共勉!!!