队列特点:先进先出的线性表。只能在表尾插入数据,表头删除数据。
顺序队列:由用数组作为队列的存储空间、队头和队尾的指针组成。
一般操作:创建、入队、出队、队空、队满
一直入队会导致队满然后出队导致队空,会造成假溢出,用循环队列解决。
循环队列的两个关键条件:
队空 front = rear 队满 (rear+1)%maxlen = front //有一个节点不放数据
队列的结构定义如下:
typedef int datatype;
#define MAXSIZE 8
typedef struct seqqueue{
datatype data[MAXSIZE];
int front,rear;
}seq_queue,*seq_pqueue;
队列的基本操作实现代码如下:
void init_seqqueue(seq_pqueue * Q) //创建队列
{
if((*Q = (seq_pqueue)malloc(sizeof(seq_queue))) == NULL)
{
printf("malloc failed!\n");
return ;
}
(*Q)->front = (*Q)->rear = MAXSIZE-1; //循环队列
//一般队列 (*Q)->front = (*Q)->rear = -1;
}
bool is_full_seqqueue(seq_pqueue q) //队满
{
if((q->rear+1)%MAXSIZE == q->front)
return true;
else
return false;
}
bool in_seqqueue(datatype data,seq_pqueue q) //入队
{
if(is_full_seqqueue(q)){ //判断是否为满
printf("queue is full\n");
return false;
}
q->rear = (q->rear+1)%MAXSIZE;
q->data[q->rear] = data;
return true;
}
bool is_empty_seqqueue(seq_pqueue q) //队空
{
if(q->rear == q->front)
return true;
else
return false;
}
bool out_seqqueue(seq_pqueue q,datatype *D) //出队
{
if(is_empty_seqqueue(q)){ //判断是否为空
printf("队列已经空\n");
return false;
}
q->front = (q->front+1)%MAXSIZE; //指针移动
*D = q->data[q->front];
return true;
}
void show_seqqueue(seq_pqueue q)
{
int i;
if(is_empty_seqqueue(q))
return ;
//循环队列的打印
for(i =(q->front+1)%MAXSIZE; i!=(q->rear+1)%MAXSIZE; i=(i+1)%MAXSIZE)
{
printf("%d ",q->data[i]);
}
puts("");
}
反思:
了解队列的特性,在使用常规队列的时候容易发生 假溢出,考虑使用循环队列。
循环队列需注意的两个关键点:队空 front = rear 队满:(rear+1)%maxlen = front
打印循环队列时的 循环条件要注意,需要取余。
可以使用单链表或者循环链表来实现队列的功能特点。