1. 栈Stack
1.1 栈简介
栈是先进后出的数据结构,限定只能在栈顶进行插入和删除操作。
1.2 相关函数
头文件
#include<stack>
常用操作
stack<int> S;//创建一个栈
S.pop();//弹出栈顶元素(删除栈顶元素)
S.top();//查看栈顶元素
S.push(a);//将a放在栈的顶部
s.empty();//返回栈是否为空
s.size();//返回栈的大小
2. 队列Queue
2.1 队列简介
队列与栈一样,是一种线性存储结构,它具有如下特点:
① 队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构。
② 在队尾添加元素,在队头添加元素。
2.2 相关函数
头文件
#include<queue>
常用操作
getSize() 获取队列中有效元素的个数
isEmpty() 判断是否为空
clear() 清空队列
enqueue() 入队
dequeue() 出队
getFront() 获取队首元素
getRear() 获取队尾元素
2.3 队列类型
顺序队列:用数组实现顺序队列
规定:队头front、队尾rear、入队enQueue、出队deQueue
① 初始化时,数组的front和rear都指向0,表示队列为空
② 入队两个元素,front不变,rear+2;
③ 出队一次,front+1;
这样实现队列,有很大的问题:
每个空间域只能利用一次,即:当队首弹出以后,front向后移动,前面的空间无法利用,造成空间极度浪费。并且非常容易越界
循环队列:对已经申请的(数组)内存重复利用
① 问题
循环队列中,空队特征是front = rear, 队满时也会有front = rear; 判断条件将出现二义性
② 解决方案
a. 标志位法:加设标志位flag
-初始flag置为false;
-元素入队flag = true,元素出队flag = false
-在触发rear = front 的上一个操作决定了是空还是满。
队空: front = rear && flag=false,
队满: front = rear && flag=true
b. 计数器法:使用一个计数器记录队列中元素个数(即队列长度)
c. 空闲单元法:人为浪费一个单元,令队满特征为 front = (rear +1)%N(%取余)——最常用方法
下面重点讲空闲单元法:
① 循环队列必须给定最大值N
② 队列添加和删除的过程,即rear和front互相追赶,如果rear追到head说明队列满了,如果front追到rear说明队列为空
循环队列实现过程
① 添加元素时:(rear+1)%N
② 删除元素时:(front+1)%N
③ 当rear=front的时候,队列可能是满,也可能是空,需要区分判断
满:当队列添加元素到rear的下一个元素是head的时候,也就是转圈子要碰头了,我们就认为队列满了。(Q.rear+1)%N=Q.front
空:当队列删除元素到head=rear的时候,我们认为队列空了Q.rear==Q.front,不一定为0
队空条件:front=rear
队满条件:front= (rear +1)%N
队列长度:L=(N+rear-front)%N