保研复习数据结构记(2)--栈,队列

 其实无论是栈还是队列,实现的物理结构都是顺序表或者是链表

不过是“栈顶”,“队头”,“队尾”等变量赋予了这块存储空间(线性表)不同的使用方法

当然这种使用方法是方便于程序员解决问题

 一.栈 

1.栈基本定义

  • 什么是栈(Stack)?:只允许在一端进行插入或者删除的线性表
  • 有什么特点?:后进先出LIFO
  • 什么是栈顶?允许进行插入删除的一端。什么是栈底?不允许进行插入删除的一端
  • 什么是卡特兰数?:有n个不同元素进栈,出栈元素不同排列个数为:                               

2.栈基本操作

#define MaxSize 10//定义栈中最大元素的个数 
typedef struct
{
	int data[MaxSize];//初始化一片连续的栈空间 
	int top;//栈顶指针,指向数组序号 
}SqStack;
//初始化栈
void InitStack(SqStack& S)
{
	S.top=-1;//初始栈为空 
}
//判断栈空 
bool IsEmpty(SqStack S)
{
	if(S.top==-1)//栈空 
	return true;
	else
	return false;	
} 
//新元素入栈
bool Push(SqStack& S,int e)
{
	if(S.top==MaxSize-1)//栈顶指针指的位置是有元素的位置,如果指向maxsize-1那么栈满 
	return false;
	S.data[++S.top]=e;
	return true; 
} 
//新元素出栈
bool Pop(SqStack& S,int& x)
{
	if(S.top==-1)//栈中没有元素无法出栈 
	return false;
	x=S.data[S.top];//先把栈顶元素赋值
	S.top--;//栈顶指针下移,上下两个操作取决于top初值是0还是1 
	return true; 
}
//读栈顶元素操作
bool GetTop(SqStack S,int& x)
{
	if(S.top==-1)//栈中没有元素无法读取 
	return false;
	x=S.data[S.top];//把栈顶元素赋值
	return true; 
} 

3.共享栈

  • 什么是共享栈?两个栈共享同一片存储空间,使用两个栈顶指针, 逻辑上是两个栈0和1,但是物理上是一片栈空间。
  • 共享栈满的条件是?:top0+1==top1
  • 如何初始化?: 
typedef struct
{
	int data[MaxSize];
	int top0;//0号栈栈顶指针 
	int top1;//1号栈栈顶指针 
}SqStack; 
//初始化栈
void InitStack(SqStack& S)
{
	S.top=-1;//初始栈为空 
	S.top1=MaxSize;
}

4.链栈 

二.队列 

1.队列的基本概念

  • 什么是队列?:只允许在一端进行插入,在另一端进行删除线性表
  • 队列的特点?:先进先出FIFO
  • 什么是队头?:允许进行删除的一端。什么是队尾?:允许进行插入的一端。
  • 如何判断循环队列中有多少个元素?:(rear+MaxSize-front)%MaxSize
  • 如何在不浪费存储空间的情况下判断队列有多少个元素?:在定义的时候定义一个size标记队列中元素的个数;或者使用tag来标记最近一次操作时插入还是删除

2.队列的基本操作

#define MaxSize 10
typedef struct
{
	int data[MaxSize];//定义一片连续的存储空间 
	int front,rear;//队头指针和队尾指针 
}SqQueue;
//初始化队列
void InitQueue(SqQueue& Q)
{
	Q.front=Q.rear=0;//初始时队头=队尾指针指向0 
}
//判断队列是否为空 
bool QueueEmpty(SqQueue Q)
{
	if(Q.rear==Q.front)
	return true;
	else
	return false;
}
//入队,为了真正考虑队满或者队不满,将队列看为循环队列
bool EnQueue(SqQueue& Q,int x)
{
	if((Q.rear+1)%MaxSize==Q.front)//表示队列满,不让rear和front指向同一个位置是为了和队列空区分
	return false;
	Q.data[Q.rear]=x;//入队
	Q.rear=(Q.rear+1)%MaxSize;//队尾指针+1取模
	return true; 
} 
//出队, 队头元素移出之后返回队头
bool Dequeue(SqQueue &Q,int& x)
{
	if(Q.rear==Q.front)
	return false;//队空则报错
	x=Q.data[Q.front];//赋值
	Q.front=(Q.front+1)%MaxSize;
	return false; 
} 
//获取队头元素 
bool GetHead(SqQueue Q,int &e)
{
	if(Q.front==Q.rear)
	return false;//队列满
	x=Q.data[Q.front];//返回 
	return true; 
}

3.链队列:带头节点和不带头节点

4.双端队列

  • 什么是双端队列?:只允许两端插入,两端删除的线性
  • 什么是输入受限的双端队列?:只允许一端插入,两端删除的线性表
  • 什么是输出受限的双端队列?:只允许两端插入,两端删除的线性表

三.栈和队列的算法应用实例

1.括号匹配

  • 括号匹配应用什么场景?:比如使用IDE编写代码的时候,IDE会自动检测括号匹配高亮问题
  • 括号匹配算法流程?:使用栈来存放检测到的符号,依次检测符号串,如果是左括号则进栈右括号则弹出栈顶元素进行匹配。匹配成功则进行下一个检测,匹配失败则算法停止;如果没有检测完毕但是栈空,则算法停止,匹配失败;如果检测完毕但是栈未空,算法停止,匹配失败。
bool bracketCheck(char str[],int length)
{
	stack<char> Stack;//初始化栈
	for(int i=0;i<length;++i)
	{
		if(str[i]=='('||str[i]=='{'||str[i]=='[')
		Stack.push(str[i]);//左括号入栈 
		else
		{
			char out=Stack.top();//弹出栈顶左括号进行检查
			if((out=='['&&str[i]!=']')||(out=='('&&str[i]!=')')||(out=='{'&&str[i]!='}'))
			return false;//如果左右括号不匹配停止检查 
		}
	} 
	return Stack.empty();//如果栈空,返回true,否则返回false 
} 

2.表达式求值问题

  • 什么是中缀表达式?:运算符在两个操作数中间 a+b
  • 什么是逆波兰表达式(后缀表达式)?:运算符在两个操作数后面 a b+
  • 什么是波兰表达式(前缀表达式)?:运算符在两个操作数前面
  • 如何用栈实现后缀表达式的计算?:从左往右扫描下一个元素,直到处理完所有元素,设置一个栈存放操作数若扫描到操作数则压入栈,并回到第一步,否则执行下一步;若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结果压回栈顶,回到第一步。如果表达式合法,最终栈的元素就是结果。
  • 中缀表达式转后缀表达式?:
  1. 初始化一个栈,用于保存暂时还不能确定运算顺序的运算符
  2. 从左到右处理各个元素,直到末尾。遇到操作数,直接加入后缀表达式
  3. 遇到界限符,遇到“(”直接入栈,遇到“)”则依次弹出栈内运算符,并加入后缀表达式,直到弹出“(”为止,但是“(”不加入后缀 表达式
  4. 遇到运算符,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若遇到“(”或栈空则停止,之后再把当前运算符入栈。
  • 如何用栈实现中缀表达式的计算?:
  1. 初始化两个栈,操作数栈和运算符栈
  2. 扫描到操作数,则压入操作数栈
  3. 扫描到运算符或者界限符,则按照中缀转后缀的逻辑压入运算符栈。(期间也会弹出运算符,每当弹出一个运算符时,就需要再弹出两个操作数栈的栈顶元素并执行相应运算,运算结果再压回操作数栈)

3.栈在递归中的应用

  • 函数调用的特点?:最后被调用的函数最先执行结束(LIFO)
  • 递归调用有什么缺点?:太多层递归可能会导致栈溢出,递归空间复杂度很高,递归太多层可能会出现重复计算的情况。

4.用队列进行树的层次遍历(见图论部分)

5.用队列对图进行广度优先遍历(见图论部分)

6.操作系统使用先来先服务FCFS(队列)来调度系统资源。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值