(1)队列的基本概念
队头:允许删除元素的一端;
队尾:允许插入元素的一端。
2)队列的顺序存储结构
#include <stdio.h>
#define MaxSize 10
typedef struct SeQueue
{
int data[MaxSize];
int front,rear;
};
//初始化队列,队头、队尾指针均指0
void InitQueue(SeQueue &Q){
Q.front=0;
Q.rear=0;
}
//队列判空:队头与队尾指向相同空间,即差值为0,队空
bool QueueEmpty(SeQueue Q)
{
return (Q.front==Q.rear);
}
//入队操作:先将数据插入至队尾,再将尾指针后移
bool EnQueue(SeQueue &Q,int x)
{
if((Q.rear+1)%MaxSize==Q.front) return false; //判断队列是否满,满则返回false,这里牺牲了一个存储空间用来区分队满和队空
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%MaxSize; //这里要注意!由于这种方式实现的队列在逻辑上似乎是循环的,也称作循环队列
return true;
}
//出队操作:先将数据取出,再将头指针后移
bool DeQueue(SeQueue &Q,int &x)
{
if(Q.front==Q.rear) return false; //判断是否队空
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
}
//查;获取队头元素
bool GetHead(SeQueue Q,int &data)
{
if(Q.front==Q.rear) return false;
data=Q.data[Q.front];
return true;
}
int main(void)
{
SeQueue Q;
int x;
int data;
InitQueue(Q);
printf("队列是否为空:%d\n",QueueEmpty(Q));
EnQueue(Q,1);
printf("队列是否为空:%d\n",QueueEmpty(Q));
GetHead(Q,data);
printf("队头元素为:%d\n",data);
DeQueue(Q,x);
printf("队列是否为空:%d\n",QueueEmpty(Q));
return 0;
}队列元素个数:(Q.rear-Q.front+MaxSize)%MaxSize;
如果想要不浪费一个存储空间用来区分队满与队空,我们可以使用一个在队列中定义一个size用来记录元素个数,初始设为0,增加元素size++,减少元素size--,队满条件size= =Maxsize,队空条件为:size= =0;
也可以设置tag,删除tag置为0,插入tag置为1,队满一定是因为插入,tag一定为1;
3)队列的链式存储结构
#include <stdio.h>
#include <stdlib.h>
//定义链式队列结点
typedef struct LinkNode
{
int data;
LinkNode * next;
}LinkNode;
//定义链式队列
typedef struct
{
LinkNode * front,* rear;
}LinkQueue;
//初始化(带头结点)
void InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=(LinkNode *)malloc(sizeof(LinkNode));
Q.front->next=NULL;
}
//队列判空:如果头、尾指针指向同一个结点或者头结点的next指向为NULL则为空
bool QueueEmpty(LinkQueue Q)
{
return (Q.front->next==NULL);
//return (Q.front=Q.rear);
}
//入队操作(带头结点)
void EnQueue(LinkQueue &Q,int x)
{
//申请一个新的结点用于存储待插入的数据
LinkNode * p=(LinkNode *)malloc(sizeof(LinkNode));
p->data=x;
//将新结点入队,即在队尾插入新结点
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
//出队操作(带头结点)
void DeQueue(LinkQueue &Q,int &x)
{
LinkNode * p;
p=Q.front->next;
x=p->data;
Q.front->next=p->next;
//!!如果删除的元素为表尾结点,要将尾指针指向头结点
if(Q.rear==p)Q.rear=Q.front;
free(p);
}
//带头结点版本
int main(void)
{
int x;
LinkQueue Q;
InitQueue(Q);
printf("队列是否为空:%d\n",QueueEmpty(Q));
EnQueue(Q,2);
printf("队列是否为空:%d\n",QueueEmpty(Q));
DeQueue(Q,x);
printf("删除的元素为:%d\n",x);
printf("队列是否为空:%d\n",QueueEmpty(Q));
return 0;
}
#include <stdio.h>
#include <stdlib.h>
//定义链式队列结点
typedef struct LinkNode
{
int data;
LinkNode * next;
}LinkNode;
//定义链式队列
typedef struct
{
LinkNode * front,* rear;
}LinkQueue;
//初始化队列(不带头结点):使front、rear都指向NULL
void InitQueue1(LinkQueue &Q)
{
Q.front=NULL;
Q.rear=NULL;
}
//判断队列是否为空(不带头结点)
bool QueueEmpty1(LinkQueue Q)
{
return (Q.front==NULL);
}
//入队操作(不带头结点)
void EnQueue1(LinkQueue &Q,int x)
{
//申请一个结点用来存储入队数据
LinkNode * p=(LinkNode *)malloc(sizeof(LinkNode));
p->data=x;
//执行入队操作
p->next=NULL;
if(Q.rear==NULL)
{
Q.front=p;
Q.rear=p;
}
else
{
Q.rear->next=p;
Q.rear=p;
}
}
//出队操作(不带头结点)
void DeQueue1(LinkQueue &Q,int &x)
{
LinkNode * p=Q.front;
x=p->data;
Q.front=p->next;
//如果出队恰好使最后一个结点,那么要把rear恢复为NULL
if(Q.rear==p)
Q.rear=NULL;
free(p);
}
int main(void)
{
int x;
LinkQueue Q;
InitQueue1(Q);
printf("队列是否为空:%d\n",QueueEmpty1(Q));
EnQueue1(Q,2);
printf("队列是否为空:%d\n",QueueEmpty1(Q));
DeQueue1(Q,x);
printf("删除的元素为:%d\n",x);
printf("队列是否为空:%d\n",QueueEmpty1(Q));
return 0;
}
京公网安备 11010502036488号