队列是具有一定操作约束的线性表,插入只能在队尾,删除只能在队头。
具有先入先出的特点。
操作集:
①创建一个空队列;
②判断队列是否已满;
③判断队列是否为空;
④将元素插入队列中;
⑤删除队头元素。
顺序实现:
建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针front,它指向队头元素;另一个是队尾指针rear,它指向下一个入队元素的存储位置
每次在队尾插入一个元素是,rear增1;每次在队头删除一个元素时,front增1。随着插入和删除操作的进行,队列元素的个数不断变化,队列所占的存储空间也在为队列结构所分配的连续空间中移动。
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct QNode* Queue;
struct QNode{
int data[MAX];
int front;
int rear;
};
//初始化
Queue Init(){
Queue PtrQ=(Queue)malloc(sizeof(QNode*));
PtrQ->front=PtrQ->rear=-1;//初始化队头和队尾都为-1
return PtrQ;
}
//添加
void Add(Queue PtrQ,int x){
if((PtrQ->rear+1)%MAX==PtrQ->front){
printf("队列已满");//%MAX避免假溢出
return;
}else{
PtrQ->data[(++PtrQ->rear)%MAX]=x;
}
}
//删除
int Delete(Queue PtrQ){
if(PtrQ->front==PtrQ->rear){
printf("队列为空");//队头和队尾重合
return -1;
}else{
return PtrQ->data[(++PtrQ->front)%MAX];
}
}
顺序队列中的溢出现象:
(1) "下溢"现象:当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。
(2)"真上溢"现象:当队列满时,做进栈运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。
(3)"假上溢"现象:由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。该现象称为"假上溢"现象。
链式实现:
队列采用的FIFO(first in first out),新元素(等待进入队列的元素)总是被插入到链表的尾部,而读取的时候总是从链表的头部开始读取。每次读取一个元素,释放一个元素。所谓的动态创建,动态释放。因而也不存在溢出等问题。
#include<stdlib.h>
#define MAX 100
typedef struct QNode* Queue;
struct QNode{//链队列结构
struct Node* front;//指向队头
struct Node* rear;//指向队尾
};
struct Node{
int data;
struct Node* next;
};
//初始化空队列
Queue Init(){
Queue PtrQ;
PtrQ->front=PtrQ->rear=(Node*)malloc(sizeof(Node*));//队头队尾指向同一块node区
PtrQ->front->next=NULL;
return PtrQ;
}
Node* creat_node(int x){
Node* s=(Node*)malloc(sizeof(Node*));
s->data=x;
s->next=NULL;
return s;
}
void Add(Queue PtrQ,int x){
Node* s=creat_node(x);
if(PtrQ->front==NULL){
PtrQ->front->next=s;
PtrQ->rear->next=s;
}
else{
PtrQ->rear->next=s;
PtrQ->rear=s;
}
}
int Delete(Queue PtrQ){
struct Node* FrontCell;
int FrontData;
if(PtrQ->front==NULL){
printf("队列为空");
return -1;
}
FrontCell=PtrQ->front;
if(FrontCell==PtrQ->rear){
PtrQ->rear=PtrQ->front=NULL;
}else{
PtrQ->front=PtrQ->front->next;
}
FrontData=FrontCell->data;
free(FrontCell);
return FrontData;
}
//测试
int main(){
Queue PtrQ=Init();
Add(PtrQ,1);
Add(PtrQ,2);
Add(PtrQ,3);
Add(PtrQ,4);
Delete(PtrQ);Delete(PtrQ);printf("%d",PtrQ->front->next->data);printf("%d",PtrQ->rear->data);
}