CODE
一般的队列有
入队: rear=(rear+1)%size
出队: front=(front+1)%size
队满: (rear + 1)%size=front
队空: rear=front
队列元素个数: (rear+size-front)%size
(以下内容都省略了结构体,合法语句应该是结构体后面带 “.”)
注意:在这种队列中,队满时rear指向的是空元素,这个位置没有被利用,我们可以在结构体中设置队列长度length=0或size来判断队满或队空,在这种情况下上面出队元素个数的公式不再适用(rear=front,可能表示队空或队满,导致结果都为0)
#define MAXSIZE 4
// 2.1 顺序队列
// (1) 线性逻辑结构,顺序存储结构
// (2) 顺序表用Length表示长度,栈用top表示长度,而队列用front和rear表示长度,三者都用数组装数据
// (3) 对于链式存储结构来说,一般不会设置长度,需要通过遍历所有元素来获得长度(到目前学的是这样子)
// ===> 第一种顺序队列
typedef struct {
int data[MAXSIZE];
int front;
int rear;
}SeqQue;
// (1) 队空: rear=front 队满: (rear + 1) % MAXSIZE = front(这样会浪费掉一个存储空间,因为rear指向的还没有被存储)
// (2) 队列元素个数 = (rear+MAXSIZE-front)%MAXSIZE
// (3) 入队出队、判断空满 代码写的是这一种
bool isEmpty01(SeqQue queue){
return queue.rear == queue.front;
}
bool isFull01(SeqQue queue){
return queue.rear + 1 == queue.front;
}
int getLen(SeqQue queue){
return (queue.rear+MAXSIZE-queue.front)%MAXSIZE;
}
//===============================================================
// ===> 第二种队列,长度用于区分rear==front是满还是空,可以有效利用空位
typedef struct {
int data[MAXSIZE];
int front;
int rear;
int length;
}SeqQue02;
// 队空: queue.length == 0 队满: queue.length == MAXSIZE
// 队空或队满都有rear = front, 不再成为判断条件
// 每进行一次入队,长度加1,出队长度-1(下面代码没有实现)
bool isEmpty02(SeqQue02 queue){
return queue.length == 0;
}
bool isFull02(SeqQue02 queue){
return queue.length == MAXSIZE;
}
// ===> 还有第三种,详见ppt
// 队列初始化
// (1) 让front和rear都指向0
// Tip:
// (1) 对于一般实现的顺序队列来说,rear=front是队列为空的判断条件
bool initQueue(SeqQue &queue){
queue.front = queue.rear = 0;
return true;
}
// 入队
// (1) 如果队未满,则向rear指向的位置塞进数据
// (2) 让rear+1再模长度
bool enterQueue(SeqQue &queue, int ele){
if (isFull01(queue)){ // 判满条件
return false;
}
queue.data[queue.rear] = ele;
queue.rear = (queue.rear+1) % MAXSIZE;
return true;
}
// 出队
// (1) 如果队不空,则将front指向的数据拿出来
// (2) 让front+1再模长度
bool leftQueue(SeqQue &queue, int &a){
if (isEmpty01(queue)){ // 判空条件
return false;
}
a = queue.data[queue.front];
queue.front = (queue.front+1) % MAXSIZE;
return true;
}
int main() {
SeqQue queue;
initQueue(queue);
enterQueue(queue,10);
enterQueue(queue,5);
enterQueue(queue,4);
printf("length=%d\n", getLen(queue));
int a;
leftQueue(queue,a);
printf("%d\t",a);
leftQueue(queue,a);
printf("%d\t",a);
leftQueue(queue,a);
printf("%d\n",a);
printf("front=%d,rear=%d,empty=%d\n",queue.front,queue.rear, isEmpty01(queue));
}
思考
这里给出的是rear指向队尾后一个位置的实现方式,当rear指向的是对位元素又有那些变化呢?
初始化/判空/判满
初始化:让front指向0的位置,让rear指向size-1的位置
队空:如图
队满:如图
入队
入队时应该先让rear后移一位,即rear=(rear+1)%size,再向指向的位置塞进去数据
出队
按照之前的方法。