题目
如果允许在循环队列的两端都可以进行插入和删除操作,写出从队尾删除和从队头插入的算法。
分析
用一维数组data[0,.... maxSize 1]实现循环队列,其中maxSize 是队列长度。设置队头指针front和队尾指针rear,约定front指向队头元素的前位置, rear指向队尾元素。 定义满足 front- rear时为队空。从队尾删除元素,则rear向着下标减小的方向行走:从队头插入元素,front 同样向着下标减小的方向行走。因此,当满足rear==(front-1+maxSize)%maxSize时队满。
从队尾删除和从队头插入的图解:
从队头删除和从队尾删除的图解:
注意两张图的箭头指向。
代码
核心代码:
/* 入队(从队头插入) */
/* &qu指的是要插入元素的队列;x指的是要插入的元素 */
int enQueue(SqQueue &qu,int x) {
if(qu.rear==(qu.front-1+maxSize)%maxSize) { // 如果队满,则不能入队
return 0;
} else {
/* 注意:这里是先入队,再修改指针 */
qu.data[qu.front]=x;
qu.front=(qu.front-1+maxSize)%maxSize;
return 1;
}
}
/* 出队(从队尾出队)
/* &qu指的是要出队的队列;&x指的是要存储出队元素的值 */
int deQueue(SqQueue &qu,int &x) {
if(qu.rear==qu.front) { // 如果队空,就不能出队了
return 0;
} else {
/* 注意:这里是先入队,再修改指针 */
x=qu.data[qu.rear];
qu.rear=(qu.rear-1+maxSize)%maxSize;
return 1;
}
}
完整代码:
#include<stdio.h>
#define maxSize 10
/* 顺序队类型定义 */
typedef struct {
int data[maxSize];
int front;// 队首指针
int rear;// 队尾指针
} SqQueue;
/* 初始化队列 */
void initQueue(SqQueue &qu) {
qu.front=qu.rear=0;// 队首和队尾指针重合并指向0
}
/* 入队(从队头插入) */
/* &qu指的是要插入元素的队列;x指的是要插入的元素 */
int enQueue(SqQueue &qu,int x) {
if(qu.rear==(qu.front-1+maxSize)%maxSize) { // 如果队满,则不能入队
return 0;
} else {
/* 注意:这里是先入队,再修改指针 */
qu.data[qu.front]=x;
qu.front=(qu.front-1+maxSize)%maxSize;
return 1;
}
}
/* 出队(从队尾出队)
/* &qu指的是要出队的队列;&x指的是要存储出队元素的值 */
int deQueue(SqQueue &qu,int &x) {
if(qu.rear==qu.front) { // 如果队空,就不能出队了
return 0;
} else {
/* 注意:这里是先入队,再修改指针 */
x=qu.data[qu.rear];
qu.rear=(qu.rear-1+maxSize)%maxSize;
return 1;
}
}
/* 打印队列 */
void printQueue(SqQueue qu) {
printf("\n");
while(qu.rear!=qu.front) {
qu.front=(qu.front+1)%maxSize;
printf("%d\t",qu.data[qu.front]);
}
printf("\n");
}
int main() {
SqQueue qu;
initQueue(qu);
int nums[]= {1,2,3,4,5,6};
int n=6;
for(int i=0; i<n; i++) {
int m=enQueue(qu,nums[i]);// 将数组中的元素入队
}
printQueue(qu);// 打印队列
int x;
deQueue(qu,x);// 将元素1出队
printQueue(qu);// 打印队列
return 0;
}
允许结果: