1.说明
  队列可以由数组实现也可由链表实现。
1.1使用数组实现
直接使用数组实现的时候因为队列满了之后(Q.front = =Q.rear) 为 true 之后这个队列便不能继续使用。为了防止这种现象发生多采用循环队列。循环队列简述 :循环队列 想像一个队列 队头 队尾;相连接之后变为一个 环状结构,其尾指针移动到队尾之后直接从 0进入重新开始;使用循环队列时因为判空,与判满都会是 Q.front = =Q.rear 所以提出以下三种策略。
- 可以空出来一个存储的位置。 这样可以区别出队空与队满;
- 可以设置 flag flag = 0 时没有元素在队列中 flag = 1时表示队列中有元素
- 记录进入队列中元素的个数
代码如下
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 5
//使用数组构造 循环队列结构体
typedef int ElemType;
typedef struct Queue{
ElemType data[MaxSize];
int front,rear;
}SqQueue;
/*
初始化队列
void InitQueue(SqQueue &Q);
判断队列是否为空
bool QueueEmpty(SqQueue Q);
判断队列是否满了
bool QueueOverFlow(SqQueue Q);
进入队列操作
bool EnQueue(SqQueue &Q,ElemType x);
出队操作
bool DeQueue(SqQueue &Q,ElemType &x);
读出队头的操作
bool GetHead(SqQueue Q,ElemType &x);
*/
// 循环队列的 初始 化是两个指针都指向 0 位置
void InitQueue(SqQueue &Q){
Q.front = Q.rear = 0;
}
bool QueueEmpty(SqQueue Q){
if(Q.front == Q.rear) return true;
else return false;
}
bool QueueOverFlow(SqQueue Q){
if((Q.rear+1)%MaxSize == Q.front) return true;
else return false;
}
bool EnQueue(SqQueue &Q,ElemType x){
if((Q.rear+1)%MaxSize==Q.front) return false;
Q.data[Q.rear]=x;
Q.rear = (Q.rear+1)%MaxSize;
return true;
}
bool DeQueue(SqQueue &Q,ElemType &x){
if(Q.rear==Q.front) return false;
x = Q.data[Q.front];
Q.front = (Q.front+1)%MaxSize;
return true;
}
bool GetHead(SqQueue Q,ElemType &x){
if(Q.rear==Q.front) return false;
x=Q.data[Q.front];
return true;
}
int main(){
SqQueue Q;
bool ret;
ElemType element;
InitQueue(Q);
ret=QueueEmpty(Q);
if(ret){
printf("the queue is empty\n");
}else{
printf("the queue is not empty\n");
}
EnQueue(Q,0);
EnQueue(Q,1);
EnQueue(Q,2);
EnQueue(Q,3);
ret = EnQueue(Q,4);
if(ret){
printf("the queue is not overflow\n");
}else{
printf("the queue is overflow\n");
}
ret=DeQueue(Q,element);
if(ret){
printf("quit Q element is%d \n",element);
}else{
printf("is defeated to quit Q\n");
}
ret = QueueOverFlow(Q);
if(ret){
printf("the queue is overflow\n");
}else{
printf("the queue is not overflow\n");
}
return 0;
}
1.1使用链表实现
队列用链表实现的话,使用的是带有头结点的单链表。有这么个问题 为什么使用带头结点的链表,而不是不带头结点链表。这个事情在之前学习链表时就遇到过,当时书上讲是因为不带头节点的链表在操作上会比较复杂,不具普适性。 在列表这儿可以体现一点点。 实际上有无头结点都可以实现队列。只是没有头结点在判空,出队操作中稍微有些复杂而已。下面是有头结点的单链表实现队列。
如下代码
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct QNode
{
ElemType data;
struct QNode *next;
}QNode;
typedef struct
{
QNode *front,*rear;
}LinkQueue;
void InitQueue(LinkQueue &Q){
Q.front=Q.rear=(QNode*)malloc(sizeof(QNode));
Q.front->next= NULL;
}
bool IsEmpty(LinkQueue &Q){
if(Q.front==Q.rear)return true;
else return false;
}
bool EnQueue(LinkQueue &Q,ElemType x){
QNode *s = (QNode *)malloc(sizeof(QNode));
s->data = x;
s->next = NULL;
Q.rear->next = s;
Q.rear = s;
return true;
}
bool DeQueue(LinkQueue &Q,ElemType &x){
if(Q.front==Q.rear) return false;
QNode *p = Q.front->next;
x = p->data;
Q.front->next=p->next;
if(p==Q.rear)
Q.rear = Q.front;
free(p);
return true;
}
int main(){
LinkQueue Q;
bool ret;
ElemType element;
InitQueue(Q);
ret = EnQueue(Q,3);
if(ret){
printf("success\n");
}else{
printf("defeat\n");
}
EnQueue(Q,4);
EnQueue(Q,5);
EnQueue(Q,6);
EnQueue(Q,7);
ret=DeQueue(Q,element);
if(ret){
printf("quit Q element is %d\n",element);
}else{
printf("defeated to quit Q\n");
}
return 0;
}
/*
输出数据:
success
quit Q element is 3
*/