栈(Stack)和队列(Queue)

1、栈(先进后出)

定义:只允许在一端 进行插入或者删除操作的线性表
基本结构图如下:
栈

注:n个不同元素进入栈,能够获取:​​ C 2 n n n + 1 \dfrac {C^n_{2n}}{n+1} n+1C2nn(卡特兰数)个不同出栈序列

a.顺序栈

利用一组地址连续的存储单元存放自栈底栈顶的数据元素

#define MaxSize 50 //定义栈的空间大小
typedef struct{
	int data[MaxSize]; //存储元素
	int top; //栈顶指针
}SqStack;

注意:1、空栈条件top == -1;
2、栈满条件S.top == MaxSize-1;

b.链式栈

通常情况栈的插入和删除在表头进行,链式结构如下

在这里插入图片描述

typedef struct Linknode{
	int data; //数据域
	struct Linknode *next; //指针域
}*LiStack;

注意:1、在进行数据结构类条件判断时,需注意指针所对应的初始位置。指针指向会影响到对应操作(如此处的栈空、栈满条件)
2、空栈top == NULL;
3、不存在栈满溢出情况

c.基本操作(顺序存储)
  1. 初始化
void InitStack(SqStack &S){
	S.top = -1; //初始化栈顶指针
}
  1. 判断栈空
bool IsEmpty(SqStack S){
	if(S.top == -1)
		return true; //栈空
	else
		return false;
}
  1. 进栈
bool Push(SqStack &S, int x){
	if(S.top == MaxSize-1) //栈满?
		return false;
	S.data[++S.top] = x; //指针加1,然后入栈
	return true;
}
  1. 出栈
bool Pop(SqStack &S, int &x){
	if(S.top == -1) //栈空?
		return false;
	x = S.data[S.top--]; //先出栈,指针减1
	return true;
}

2、队列(先进先出)

定义:单向进行插入、删除的线性表
在这里插入图片描述

注意:队列操作,不可以随意读取队列中的某个数据。

a.顺序存储
#define MaxSize 50  //定义元素的最大个数
typedef struct{
	int data[MaxSize]; //存放队列元素
	int front, rear; //队头指针和队尾指针
}SqQueue;
b.链式存储
typedef struct{ //链式队列结点
	int data;
	struct LinkNode *next;
}LinkNode;
typedef struct{ //链式队列
	LinkNode *front,*rear;
}LinkQueue;
c.基本操作(链式存储)
  1. 初始化
void InitQueue(LinkQueue &Q){
	Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode)); //建立头结点
	Q.front->next = NULL; 
}
  1. 判断队空
bool IsEmpty(LinkQueue Q){
	if(Q.front == Q.rear)
		return true;
	else 
		return false;
}
  1. 入队
void EnQueue(LinkQueue &Q, int x){
	LinkNode *s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x; //创建新结点,插入到链尾
	s->next = NULL;
	Q.rear->next = s;
	Q.rear = s;
}
  1. 出队
bool DeQueue(LinkQueue &Q, int &x){
	if(Q.front == Q.rear) return false; //空队
	LinkNode *p = Q.front->next;
	x = p->data;
	Q.front->next = p->next;
	if(Q.rear == p)
		Q.rear = Q.front; //原队列只有一个结点,删除后变空
	free(p);
	return true;
}
d.循环队列

(引入循环队列,为了防止判别队满情况时出现“假溢出”现象)
入队:rear = (rear+1)%MaxSize //队尾指针加1
出队:front = (front+1)%MaxSize //队首指针加1
队列长度:(rear+Maxsize-front)%Maxsize

判断队空队满

  1. 入队时少用一个队列单元
    队满:(Q.rear+1)%Maxsize == Q.front
    队空:Q.front == Q.rear
  2. 设计数器
    初始count=0,入队成功count+1,出队成功count-1
    队满:count == MaxSize 或count>0 && rear == front
    队空:count == 0
  3. 增设标志位flag
    初始值为0,入队成功后flag=1,出队成功flag=0
    队满:rear == front && flag=1
    队空:rear == front && flag=0
e.双端队列

引用别人的一张图说明
在这里插入图片描述


考研小注:

  1. 判断出栈序列合法性
  2. 循环队列的原理和性质
  3. 进队和出队的操作
  4. front和rear初值(不固定)的推断
  5. 队列中元素个数的计算
  6. 判空和判满的条件
  7. 输出受限、输入受限的双端队列的出队序列合法性
  8. 栈和队列的应用及特点
  9. 出入栈的过程中栈的至少容量
  10. 栈在递归中的应用
  11. 栈在表达式求值中的应用
  12. 中缀表达式转为后缀表达式
  13. 特殊矩阵(对称矩阵、上三角矩阵、下三角矩阵)的压缩存储

小狼的相关博文:
14. 算法(Algorithm)与数据结构(Data Structure)——索引

  1. 数据结构和算法系列代码测试代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值