队列的基本概念
队列也是一种特殊的线性表,队列的数据元素及数据元素间的逻辑关系和线性表完全相同,其差别是:线性表允许在任何位置插入和删除数据元素,而队列只允许在其一端进行插入操作,在其另一端进行删除操作。
队列中,允许进行插入操作的一段成为队尾,允许进行删除操作的一段称为对头。对头和队尾分别由对头指示器(或称队头指针:front)和队尾指示器(或称队尾指针:rear)指示。队列的插入操作通常称为入队列,队列的删除操作通常称为出队列。
队列是一种先进先出的线性表,简称先进先出表。
数组模拟队列
maxSize: 该队列的最大容量。
- rear指向队列最后元素
- front指向队列最前元素的前一个
- 队列空的条件是:front == rear
- 队列满的条件是:rear == maxSize - 1
顺序队列的“假溢出”问题
顺序队列因多次入队列和出队列操作后出现的尚有存储空间但不能进行入队列操作的溢出称作假溢出。简单地说,就是顺序队列只能使用一次,没有达到复用的效果。可以改进成顺序环形队列避免这个问题。顺序环形队列将在下一个博客展示。
顺序队列的C语言实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define maxSize 5
typedef struct{
int queue[maxSize];
int rear; //队尾
int front; //对头
}Struct_ArrayQueue; //队列结构体
//初始化队列
void QueueInitiate(Struct_ArrayQueue *Q){
memset(Q->queue, 0x00, sizeof(Q->queue)); //初始化队列
Q->front = -1; //初始化对头 ,指向队列头部的前一个位置
Q->rear = -1; //初始化队尾 ,指向队列尾部的具体数据
}
//判断队列满
int isFull(Struct_ArrayQueue Q){
if(Q.rear == maxSize - 1)
return 1; //队列满返回1
else
return 0; //队列没满返回0
}
//判断队列是否空
int isEmpty(Struct_ArrayQueue Q){
if(Q.rear == Q.front)
return 1; //队列空返回1
else
return 0; //队列不空返回0
}
//添加数据到队列
int addQueue(Struct_ArrayQueue *Q, int n) {
if(Q->rear == maxSize - 1) { //判断队列是否满,满了就无法添加数据
printf("队列已满无法添加数据\n");
return 0;
}
Q->rear++; //rear后移
Q->queue[Q->rear] = n;
return 1;
}
//数据出队列, 取数据
int getQueue(Struct_ArrayQueue *Q, int *d){
//判断队列是否空
if(Q->rear == Q->front){
printf("队列为空,无数据出队列\n");
return 0;
}
Q->front++; //front后移
*d = Q->queue[Q->front]; //将数据传给d,让d带回main函数
Q->queue[Q->front] = 0; //取出后赋值为0
return 1;
}
//显示队列所有数据
void showQueue(Struct_ArrayQueue Q){
int i;
//判断是否为空
if(isEmpty(Q))
printf("队列为空,没有数据\n");
else{
for(i = 0; i < sizeof(Q.queue)/sizeof(Q.queue[0]); i++){
printf("arr[%d] = %d\n", i, Q.queue[i]);
}
}
}
//显示对头数据, 注意不是取出
int headQueue(Struct_ArrayQueue Q, int *d){
//判断是否为空
if(isEmpty(Q)){
printf("队列为空,无对头数据可显示\n");
return 0;
}
*d = Q.queue[Q.front + 1];
return 1;
}
int main(int argc, char *argv[]) {
//测试数据
Struct_ArrayQueue Q;
int loop = 1, value, res;
char key;
//初始化队列
QueueInitiate(&Q);
while(loop) {
printf("s(show): 显示队列\n");
printf("e(exit): 退出程序\n");
printf("a(add): 添加数据到队列\n");
printf("g(get): 从队列里面取数据\n");
printf("h(head): 查看队列头的数据\n");
key = getchar();
switch(key){
case 's': //显示队列
showQueue(Q);
break;
case 'a': // 添加数据到队列
scanf("%d", &value);
addQueue(&Q, value);
break;
case 'g': //从队列里面取数据
if(getQueue(&Q, &res)){
printf("取出的数据是:%d\n", res);
}
break;
case 'h': //查看队列头的数据
if(headQueue(Q, &res)){
printf("当前对列头的数据是:%d\n", res);
}
break;
case 'e':
loop = 0;
break;
default:
break;
}
getchar(); //吸收回车,避免前面的目录两次输出
}
printf("程序退出\n");
return 0;
}
本篇参考: