队列(queue)的概念及常见应用

2023-10-20 16:55:44 浏览数 (2)

队列是一种先进先出的数据模型,它的应用场景比较常见,比如日常生活中我们打10086的电话需要排队时、吃饭排号时的小票、Windows GUI程序的消息队列等等都是基于队列实现的。先进入队列的也是先从队列出去的。他的模型如下:

【顺序线性表实现队列】 顺序线性表可以实现队列的模型,线性表中哪一端作为队头或者队尾都可以的。具体实现代码如下(需要用到线性表顺序存储的头文件 SeqList.h 和 SeqList.c):

代码语言:javascript复制
#ifndef _SEQQUEUE_H_
#define _SEQQUEUE_H_
typedef void SeqQueue;
//创建队列
SeqQueue* SeqQueue_Create(int capacity);
//销毁队列
void SeqQueue_Destroy(SeqQueue* queue);
//清空队列
void SeqQueue_Clear(SeqQueue* queue);
//进队列
int SeqQueue_Push(SeqQueue* queue, void* item);
//出队列
void* SeqQueue_Pop(SeqQueue* queue);
//获取队头元素
void* SeqQueue_Front(SeqQueue* queue);
//获取队列的长度
int SeqQueue_Size(SeqQueue* queue);
#endif //_SEQQUEUE_H_
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “SeqQueue.h”
#include “SeqList.h”
//用顺序线性表来实现
//创建队列
SeqQueue* SeqQueue_Create(int capacity)
{
//创建一个线性表
return SeqList_Create(capacity);
}
//销毁队列
void SeqQueue_Destroy(SeqQueue* queue)
{
//销毁线性表
SeqList_Destroy(queue);
}
//清空队列
void SeqQueue_Clear(SeqQueue* queue)
{
//重置线性表
SeqList_Clear(queue);
}
//进队列
int SeqQueue_Push(SeqQueue* queue, void* item)
{
//数组的尾部作为队尾
//在信息表尾部插入元素
int ret = SeqList_Insert(queue, (SeqListNode*)item, SeqList_Length(queue));
return ret;
}
//出队列
void* SeqQueue_Pop(SeqQueue* queue)
{
//数组的头部作为队头
//线性表的头部删除元素
SeqListNode* pNode = SeqList_Delete(queue, 0);
return pNode;
}
//获取队头元素
void* SeqQueue_Front(SeqQueue* queue)
{
//获取线性表第一个元素
SeqListNode* pNode = SeqList_Get(queue, 0);
return pNode;
}
//获取队列的长度
int SeqQueue_Size(SeqQueue* queue)
{
//线性表长度
return SeqList_Length(queue);
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “SeqQueue.h”
//定义结构体
typedef struct tag_Value
{
int v;
}Value;
int main()
{
int i;
Value val[10];
SeqQueue* queue = NULL;
//创建队列
queue = SeqQueue_Create(20);
//初始化结构体数组
for (i = 0; i < sizeof(val) / sizeof(Value); i  )
{
val[i].v = i;
//进队列
SeqQueue_Push(queue, (void*)&val[i]);
}
//打印队列 的长度
printf(“Queue size = %dn”, SeqQueue_Size(queue));
//打印对队头元素
printf(“Queue front element = %dn”, ((Value*)SeqQueue_Front(queue))->v);
//所有元素出队列
while (SeqQueue_Size(queue) > 0)
{
//打印对队头元素, 并弹出
printf(“POP – Queue front element = %dn”, ((Value*)SeqQueue_Pop(queue))->v);
}
//销毁队列
SeqQueue_Destroy(queue);
printf(“Good good study, day day up!!!n”);
system(“pause”);
return 0;
}

【链式线性表实现队列】 使用顺序线性表可以实现队列的模型,同样链式线性表也是可以的,使用链表来实现队列模型如下:

实现代码(需要用到链式线性表头文件 LinkList.h 和 LinkList.c ):

代码语言:javascript复制
#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_
typedef void LinkQueue;
//创建队列
LinkQueue* LinkQueue_Create();
//销毁队列
void LinkQueue_Destory(LinkQueue* queue);
//清空队列
void LinkQueue_Clear(LinkQueue* queue);
//进队列
int LinkQueue_Push(LinkQueue* queue, void* item);
//出队列
void* LinkQueue_Pop(LinkQueue* queue);
//获取队头元素
void* LinkQueue_Front(LinkQueue* queue);
//获取队列长度
int LinkQueue_Size(LinkQueue* queue);
#endif //_LINKQUEUE_H_
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “LinkQueue.h”
#include “LinkList.h”
//定义一个队列节点结构体
typedef struct tag_listqueueNode
{
//包含一个链表节点
LinkListNode node;
//存储数据
void* data;
}ListQueueNode;
//创建队列 ==> 创建链表
LinkQueue* LinkQueue_Create()
{
//创建一个链表
return LinkList_Create();
}
//销毁队列
void LinkQueue_Destory(LinkQueue* queue)
{
//释放掉所有分配的存储空间
LinkQueue_Clear(queue);
//销毁这个链表
LinkList_Destory(queue);
}
//清空队列 ==> 清空链表
//因为动态分配了内存, 所有需要释放
void LinkQueue_Clear(LinkQueue* queue)
{
//释放掉所有分配的存储空间
while (LinkQueue_Size(queue) > 0)
{
LinkQueue_Pop(queue);
}
//清空链表
LinkList_Clear(queue);
}
//进队列 ==> 在链表尾部添加元素
int LinkQueue_Push(LinkQueue* queue, void* item)
{
//创建队列节点
ListQueueNode* pNew = (ListQueueNode*)malloc(sizeof(ListQueueNode));
if (pNew == NULL)
{
//创建节点失败,直接返回
return -1;
}
//初始化
pNew->data = item;
pNew->node.next = NULL;
//链表 的尾部作为队尾
//在链表 的尾部插入元素
int ret = LinkList_Insert(queue, (LinkListNode*)pNew, LinkList_Length(queue));
if (ret != 0)
{
//释放内存
free(pNew);
}
return ret;
}
//出队列 ==> 在链表头部删除元素
void* LinkQueue_Pop(LinkQueue* queue)
{
//链表的头部作为队头
//删除链表的第一个数据节点
LinkListNode *pDel = LinkList_Delete(queue, 0);
if (pDel == NULL)
{
return NULL;
}
void* data = ((ListQueueNode*)pDel)->data;
//释放内存
free(pDel);
return data;
}
//获取队头元素 ==> 获取链表的第一个数据节点
void* LinkQueue_Front(LinkQueue* queue)
{
//获取链表的第一个数据节点
LinkListNode* pNode = LinkList_Get(queue, 0);
return ((ListQueueNode*)pNode)->data;
}
//获取队列长度 ==> 获取链表的长度
int LinkQueue_Size(LinkQueue* queue)
{
//链表长度
return LinkList_Length(queue);
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “LinkQueue.h”
int main()
{
int i;
int array[10] = { 0 };
LinkQueue* queue = NULL;
//创建队列
queue = LinkQueue_Create();
//数组赋值
for (i = 0; i < sizeof(array) / sizeof(int); i  )
{
array[i] = i;
//进队列
LinkQueue_Push(queue, (void*)&array[i]);
}
//打印队列的长度
printf(“Queue size = %dn”, LinkQueue_Size(queue));
//打印队头元素
printf(“Queue Front element = %dn”, *(int*)LinkQueue_Front(queue));
//将所有元素出队列
while (LinkQueue_Size(queue) > 0)
{
//打印队头元素, 并弹出
printf(“POP == Queue Front element = %dn”, *(int*)LinkQueue_Pop(queue));
}
//销毁队列
LinkQueue_Destory(queue);
printf(“Good good study, day day up!!!n”);
system(“pause”);
return 0;
}

0 人点赞