队列是限制在两端进行插入操作和删除操作的线性表
允许进行存入操作的一端称为队尾
允许进行删除操作的一端称为队头
当线性表中没有元素时,称为空队
特点:先进先出(FIFO)
顺序队列
front指向队头元素的位置,rear指向队尾元素的下一个位置。
为区别空队和满队,满队元素个数比数组元素个数少一个。
函数 sequeue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sequeue.h"
sequeue *queue_create()
{
sequeue *sq;
if((sq=(sequeue *)malloc(sizeof(sequeue)))==NULL)
{
printf("malloc failed");
return NULL;
}
memset(sq->data,0,sizeof(sq->data));
sq->front=sq->rear=0;
return sq;
}
int enqueue(sequeue *sq,data_t x)
{
if(sq==NULL)
{
printf("sq is NULL");
return -1;
}
if((sq->rear+1)%N==sq->front)//判断rear加一后是否跟front相等,相等代表队列满了
{
printf("sequeue is full");
return -1;
}
sq->data[sq->rear]=x;
sq->rear=(sq->rear+1)%N;//使得rear+1后再次进入队列
return 0;
}
int dequeue(sequeue *sq)
{
if(sq==NULL)
{
printf("sq is NULL");
return -1;
}
data_t ret;
ret=sq->data[sq->front];
sq->front=(sq->front+1)%N;
return ret;
}
int queue_empty(sequeue *sq)
{
if(sq==NULL)
{
printf("sq is NULL");
return -1;
}
return(sq->front==sq->rear?1:0);
}
int queue_full(sequeue *sq)
{
if(sq==NULL)
{
printf("sq is NULL");
return -1;
}
if((sq->rear+1)%N==sq->front)//判断rear加一后是否跟front相等,相等代表队列满了
{
printf("sequeue is full");
return 1;
}
else
return 0;
}
int queue_clear(sequeue *sq)
{
if(sq==NULL)
{
printf("sq is NULL");
return -1;
}
sq->front=sq->rear=0;
return 0;
}
sequeue *queue_free(sequeue *sq)
{
if(sq==NULL)
{
printf("sq is NULL");
return NULL;
}
free(sq);
sq=NULL;
return NULL;
}
头文件sequeue.h
typedef int data_t;
#define N 6
typedef struct
{
data_t data[N];
int front;
int rear;
}sequeue;
sequeue *queue_create();
int enqueue(sequeue *sq,data_t x);
int dequeue(sequeue *sq);
int queue_empty(sequeue *sq);
int queue_full(sequeue *sq);
int queue_clear(sequeue *sq);
sequeue *queue_free(sequeue *sq);
测试函数 test.c
#include <stdio.h>
#include <stdlib.h>
#include "sequeue.h"
int main()
{
sequeue *sq;
if((sq=queue_create())==NULL)
{
return -1;
}
enqueue(sq,10);
enqueue(sq,20);
enqueue(sq,30);
enqueue(sq,40);
enqueue(sq,50);
while(!queue_empty(sq))
{
printf("dequeue:%d\n",dequeue(sq));
}
return 0;
}
链式队列
插入操作在队尾进行,删除操作在队头进行,由队头指针和队尾指针控制队列的操作。
函数 linkqueue.c
#include <stdio.h>
#include <stdlib.h>
#include "linkqueue.h"
linkqueue *queue_create()
{
linkqueue *lq;
if((lq=(linkqueue *)malloc(sizeof(linkqueue)))==NULL)
{
printf("malloc failed");
return NULL;
}
lq->front=lq->rear=(linklist)malloc(sizeof(listnode));
if(lq->front==NULL)
{
printf("front malloc failed");
return NULL;
}
lq->front->data=0;
lq->front->next=NULL;
return lq;
}
int enqueue(linkqueue *lq,data_t x)
{
linklist p;
if(lq==NULL)
{
printf("lq is NULL");
return -1;
}
if((p=(linklist)malloc(sizeof(listnode))==NULL))
{
printf("node malloc failed");
return -1;
}
p->data=x;
p->next=NULL;
lq->rear->next=p;
lq->rear=p;
return 0;
}
/*
为了防止队列中只有一个元素节点时,删掉后rear只能指向NULL,
可以采取出队时删除掉头结点,然后把首元结点当作头结点的方法,
此时原本首元结点中的数据看作是无意义的
*/
int dequeue(linkqueue *lq)
{
linklist p;
p=lq->front;
lq->front=p->next;
free(p);
p=NULL;
return (lq->front->data);
}
int queue_empty(linkqueue *lq)
{
if(lq==NULL)
{
printf("lq is NULL");
return -1;
}
return (lq->front==lq->rear?1:0);
}
int queue_clear(linkqueue *lq)
{
if(lq==NULL)
{
printf("lq is NULL");
return -1;
}
linklist p;
while(lq->front->next)
{
p=lq->front;
lq->front=p->next;
printf("clear:%d\n",p->data);
free(p);
p=NULL;
}
return 0;
}
linkqueue *queue_free(linkqueue *lq)
{
if(lq==NULL)
{
printf("lq is NULL");
return NULL;
}
linklist p;
while(lq->front)
{
p=lq->front;
lq->front=p->next;
printf("free:%d\n",p->data);
free(p);
}
free(lq);
lq=NULL;
return NULL;
}
头文件 linkqueue.h
typedef int data_t;
typedef struct node
{
data_t data;
struct node*next;
}listnode,*linklist;
typedef struct
{
linklist front;
linklist rear;
}linkqueue;
linkqueue *queue_create();
int enqueue(linkqueue *lq,data_t x);
int dequeue(linkqueue *lq);
int queue_empty(linkqueue *lq);
int queue_clear(linkqueue *lq);
linkqueue *queue_free(linkqueue *lq);
测试代码 test.c
#include <stdio.h>
#include <stdlib.h>
#include "linkqueue.h"
int main()
{
linkqueue *lq;
lq=queue_create();
if(lq==NULL)
{
return -1;
}
enqueue(lq,10);
enqueue(lq,20);
enqueue(lq,30);
enqueue(lq,40);
enqueue(lq,50);
while(!queue_empty(lq))
{
printf("dequeue:%d\n",dequeue(lq));
}
queue_free(lq);
return 0;
}