1. 队列的定义:
队列:是只允许一端进行数据插入,而另一端进行数据删除的线性表。(先进先出FIFO),如下图所示。
队列的应用:缓冲区,即解决高速设备和低速设备数据交互的时候,速度不匹配问题
2. 存储结构:
1. 顺序队列:循环队列
空队列:初始两个指针都指向a1元素,如下图的左图所示;
队列满的条件:(rear+1) % QueueSize == front,即牺牲空间来判断是否为满队列,如下图的右图所示。
入队时:rear指针向尾部移动,front指针则依旧指向首元素,如下图的左图所示;
出队时:front指针向下一个元素移动,释放出队元素,尾指针不变,如下图的右图所示。
我们把头尾相接的顺序存储结构称为循环队列。
1. 循环队列的定义:
typedef int DATA_TYPE;
typedef struct que
{
DATA_TYPE *pbase;
int front;
int rear;
int maxSize;
}SQE_QUE;
2. 循环队列的创建:
SQE_QUE *Create_Sqe_Queue(int maxSize)
{
SQE_QUE *psqe = malloc(sizeof(SQE_QUE));
if(psqe == NULL)
{
perror("fail to malloc");
return NULL;
}
psqe->pbase = malloc(maxSize * sizeof(DATA_TYPE));
psqe->front = 0;
psqe->rear = 0;
psqe->maxSize = maxSize;
return psqe;
}
3. 判断循环队列是否为空或满:
int Is_Empty_Sqe_Queue(SQE_QUE *psqe)
{
if(psqe->front == psqe->rear)
{
return 1;
}
return 0;
}
int Is_Full_Sqe_Queue(SQE_QUE *psqe)
{
if(((psqe->rear + 1) % psqe->maxSize) == psqe->front)
{
return 1;
}
return 0;
}
4. 入循环队列:
int Push_Sqe_Queue(SQE_QUE *psqe, DATA_TYPE data)
{
if(Is_Full_Sqe_Queue(psqe))
{
fprintf(stderr, "Queue full!\n");
return -1;
}
else
{
psqe->pbase[psqe->rear] = data;
psqe->rear = (psqe->rear+1) % psqe->maxSize;
}
return 0;
}
5. 出循环队列:
int Pop_Sqe_Queue(SQE_QUE *psqe, DATA_TYPE *data)
{
if(Is_Empty_Sqe_Queue(psqe))
{
fprintf(stderr, "Queue Empty!\n");
return -1;
}
else
{
if(data != NULL)
{
*data = psqe->pbase[psqe->front];
}
psqe->front = (psqe->front+1) % psqe->maxSize;
}
return 0;
}
6. 读取循环队列队头的数据:
int Find_Front_Sqe_Queue(SQE_QUE *psqe, DATA_TYPE *data)
{
*data = psqe->pbase[psqe->front];
return 0;
}
7. 清空循环队列:
void Clear_Sqe_Queue(SQE_QUE *psqe)
{
psqe->front = psqe->rear = 0;
return;
}
8. 销毁循环队列:
void Destory_Sqe_Queue(SQE_QUE *psqe)
{
free(psqe->pbase);
free(psqe);
return;
}
9. 循环队列的遍历(为了方便验证队列是否正确):
void Show_Queue(SQE_QUE *psqe)
{
int i = psqe->front;
while(i != psqe->rear)
{
printf("%d ", psqe->pbase[i]);
i = (i + 1) % psqe->maxSize;
}
printf("\n");
return;
}
2. 链式队列:
队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链式队列。
1. 链式队列的定义:
typedef int DATA_TYPE;
typedef struct node
{
DATA_TYPE data;
struct node *pnext;
}QUEUE_NODE;
typedef struct list
{
QUEUE_NODE *pfront;
QUEUE_NODE *preal;
int curlen;
}QUEUE_LIST;
2. 链式队列句柄的创建:
QUEUE_LIST *Create_Queue_List(void)
{
QUEUE_LIST *plist = malloc(sizeof(QUEUE_LIST));
if(plist == NULL)
{
perror("fail to malloc");
return NULL;
}
plist->pfront = NULL;
plist->preal = NULL;
plist->curlen = 0;
return plist;
}
3. 链式队列结点的创建:
QUEUE_NODE *Create_Queue_Node(DATA_TYPE data)
{
QUEUE_NODE *pnode = malloc(sizeof(QUEUE_NODE));
if(pnode == NULL)
{
perror("fail to malloc");
return NULL;
}
pnode->data = data;
pnode->pnext = NULL;
return pnode;
}
4. 入队列(尾插法):
int Is_Empty_Queue(QUEUE_LIST *plist)
{
return plist->pfront == NULL;
}
int Push_Queue_Link(QUEUE_LIST *plist, QUEUE_NODE *pnode)
{
if(plist == NULL || pnode == NULL)
{
return -1;
}
if(plist->pfront == NULL)
{
plist->pfront = pnode;
plist->preal = pnode;
}
else
{
plist->preal->pnext = pnode;
plist->preal = pnode;
}
plist->curlen++;
return 0;
}
5. 出队列(头删法):
int Pop_Queue_Link(QUEUE_LIST *plist, DATA_TYPE *data)
{
if(Is_Empty_Queue(plist))
{
return 0;
}
QUEUE_NODE *ptmp = plist->pfront;
if(ptmp->pnext == NULL)
{
plist->pfront = NULL;
plist->preal = NULL;
if(data != NULL)
{
*data = ptmp->data;
}
free(ptmp);
}
else
{
plist->pfront = ptmp->pnext;
if(data != NULL)
{
*data = ptmp->data;
}
free(ptmp);
}
plist->curlen--;
return 0;
}
6. 获取链式队列队头的数据:
int Get_Front_Quene(QUEUE_LIST *plist, DATA_TYPE *data)
{
if(Is_Empty_Queue(plist))
{
return 0;
}
QUEUE_NODE *ptmp = plist->pfront;
*data = ptmp->data;
return 0;
}
7. 清空链式队列:
void Clear_Queue(QUEUE_LIST *plist)
{
QUEUE_NODE *ptmp = plist->pfront;
while(plist->pfront != NULL)
{
Pop_Queue_Link(plist, NULL);
}
return;
}
8. 销毁链式队列:
void Destory_Queue(QUEUE_LIST *plist)
{
Clear_Queue(plist);
free(plist);
return;
}
9. 链式队列的遍历(为了方便验证队列是否正确):
void Show_Queue(QUEUE_LIST *plist)
{
QUEUE_NODE *ptmp = plist->pfront;
while(ptmp != NULL)
{
printf("%d ", ptmp->data);
ptmp = ptmp->pnext;
}
printf("\n");
return;
}