队列的基本概念
- 队列的定义:是一种先进先出的线性表,仅允许在表的一端进行插入,在表的另一端进行删除,可进行插入操作的一端称为队尾,可进行删除操作的一端称为队首。
- 队列的特点:先进先出(First In First Out,FIFO)。
- 队列的存储结构:可以分为顺序队列和链队。
队列的结构体定义
//顺序队列的定义
typedef struct{
int data[maxSize]; //数据
int front; //队首指针
int rear; //队尾指针
}SqQueue;
//链队定义
//队结点类型定义
typedef struct QNode{
int data; //数据域
struct QNode *next; //指针域
}QNode;
//链队类型定义
typedef struct {
QNode *front; //队头指针
QNode *rear; //队尾指针
}LinkQueue;
顺序队列
在顺序队中,为了解决“假溢出”问题,需要把数组变成一个环状,让front和rear沿着环走,这样就可以避免了假溢出问题,这样就形成了循环队列。
循环队列的两个状态:
- 队空状态:
qu.rear == qu.front
- 队满状态:
(qu.rear+1)%maxSize == qu.front
循环队列的两个操作:
- 元素进队:
qu.rear=(qu.rear+1)%maxSize;qu.data[qu.rear]=x;
- 元素出队:
qu.front=(qu.front+1)%maxSize;x=qu.data[qu.front];
顺序队列操作代码
//初始化队列
void initQueue(SqQueue &qu){
qu.front = qu.rear = 0;
}
//判断队空算法
int isQueueEmpty(SqQueue qu){
if(qu.front == qu.rear)
return 1;
return 0;
}
//元素入队
int enQueue(SqQueue &qu, int x){
if((qu.rear + 1)%maxSize == qu.front)
return 0;
qu.rear = (qu.rear + 1) % maxSize;
qu.data[qu.rear] = x;
return 1;
}
//元素出队
int deQueue(SqQueue &qu, int &x){
if(qu.front == qu.rear)
return 0;
qu.front = (qu.front + 1) % maxSize;
x = qu.data[qu.front];
return 1;
}
注:
在上述代码中,front头指针,若队列不空,始终指向队头元素的前一个位置,rear尾指针,若队列不空指向队尾元素。
当然我们也可以用另一种指向方式:front头指针,若队列不空,指向队头元素,rear尾指针,若队列不空指向队尾元素的下一个位置。
上述两种指针的指向方式都是可以的。
链队列
链队就是使用链式存储结构来存储队列,这里使用单链表来实现。
链式队列的两个状态:
- 队空状态:
lqu->rear==NULL或者lqu->front == NULL
- 队满状态:无法为新结点分配内存时(假设内存无限大的时候不存在队满情况)
链队的两个操作:
- 元素进队:
lqu->rear->next = p;lqu->rear = p;
- 元素出队:
p=lqu->front;lqu->front=p->next;x=p->data;free(p);
链队的基本操作代码
//初始化队列
void initQueue(LinkQueue *&lqu){
lqu = (LinkQueue *)malloc(sizeof(LinkQueue));
lqu->front - lqu->rear = NULL;
}
//判断队空
int isQueueEmpty(LinkQueue *lqu){
if(lqu->rear == NULL || lqu->front == NULL)
return 1;
return 0;
}
//入队
void enQueue(LinkQueue *&lqu, int x){
QNode *p;
p = (QNode *)malloc(sizeof(QNode));
p->data = x;
p->next = NULL;
if(lqu->rear == NULL)
lqu->front = lqu->rear = p;
else{
lqu->rear->next = p;
lqu->rear = p;
}
}
//出队
int deQueue(LinkQueue *lqu, int &x){
QNode *p;
if(lqu->rear == NULL)
return 0;
else
p = lqu->front;
if(lqu->front == lqu->rear)
lqu->front = lqu->rear = NULL;
else
lqu->front = lqu->front->next;
x = p->data;
free(p);
return 1;
}