什么是队列
队列的概念
对于队列,它也是一种受限制的线性表。(即特殊的线性表)
队列是限定所有的插入操作在表的一端进行,而删除操作在表的另一端进行的线性表。
允许进行插入的一端为队尾。
允许进行删除的一段为队头。
它具有先进先出的特性。正好与栈相反。
假设队列是q=(a1,a2,…,an),那么a1就是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,列在最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然在队伍的最后。
队列的基本操作
插入元素叫入队,删除元素叫出队。
队列的存储结构为链队和顺序队(常用循环顺序队)。
顺序队列
队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成。
队头指针指示队列中对头元素的前面一位。
队尾指针指示队列中队尾元素位置。
由于队列删除操作会使队列空间不能最大化利用。所以使用循环队列来存储。
循环队列是把一维数组头尾相接得到的。
例如这样:
由于循环队列添加元素有可能会溢出,所以入队使用取模操作来存放新元素。
顺序队列的结构
# define maxsize 100
typedef struct queue
{
element data[maxsize];
int rear;
int front;
}*queue;
初始化队列
void initqueue(queue q)
{
q->rear=q->front=maxsize-1;
}
1.入队
void add(queue p,element x)
{
if((p->rear+1)%maxsize==p->front)
{
printf("队列满\n");
return;
}
p->rear=(p->rear+1)%maxsize;
p->data[p->rear]=x;
}
2.出队
element deleteq(queue q)
{
if(q->rear==q->front)
{
printf("队列空");
return ERROR;
}
q->front=(q->front+1)%maxsize;
return q->data[q->front];
}
链式队列
队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行。链式队列只能头做删除(即front指向头结点),尾做插入(即rear指向表尾)。
链式结构
struct node//单链表
{
element data;
struct node *next;
}
typedef struct queue//链队列结构
{
struct node *front;//指向队头节点
struct node *rear;//指向队尾节点
}*queue;
1.初始化
void initqueue(queue q)
{
q->front=(struct node *)malloc(sizeof(struct node));
q->rear=q->front;
q->front->next=NULL;
}
2.入队
void enterqueue(queue q,element x)
{
struct node *a=(struct node *)malloc(sizeof(struct node));
a->data=x;
a->next=NULL;
q->rear->next=a;
q->rear=a;
}
3.出队
element deleteq(queue q)
{
struct node *a;
element x;
if(q->front==q->rear)
{
printf("队列空\n");
return ERROR;
}
a=q->front->next;
q->front->next=a->next;
if(q->rear==a)
{
q->rear=q->front;
}
x=a->data;
free(a);
return x;
}