队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
.h文件
#pragma once
#include
typedef char SeqQueueType;
#define SeqQueueMaxSize 1000
typedef struct SeqQueue
{
SeqQueueType data[SeqQueueMaxSize];
size_t head;
size_t tail;
size_t size;
}SeqQueue;
void SeqQueueInit(SeqQueue* q);//初始化
void SeqQueueDestroy(SeqQueue* q);//销毁队列
void SeqQueuePush(SeqQueue* q,SeqQueueType value);//入队列
void SeqQueuePop(SeqQueue* q);//出队列
int SeqQueueFront(SeqQueue* q,SeqQueueType* value);//取队首元素
.c文件
void SeqQueueInit(SeqQueue* q)
{
if(q == NULL)
{
//非法输入
return;
}
q->size = 0;
q->head = 0;
q->tail = 0;
return;
}
void SeqQueueDestroy(SeqQueue* q)
{
if(q == NULL)
{
//非法输入
return;
}
q->size = 0;
q->head = 0;
q->tail = 0;
return;
}
void SeqQueuePush(SeqQueue* q,SeqQueueType value)
{
if(q == NULL)
{
//非法输入
return;
}
if(q->size > SeqQueueMaxSize)//如果队列的尺寸大于队列最大尺寸,说明队列已经满了
{
//队列已经满了
return;
}
q->data[q->tail++] = value;//把value赋给数组的最后一个元素,并把数组元素下标+1
if(q->tail > SeqQueueMaxSize)//如果尾元素的下标已经超过了最大容量,就让下一个元素从0号下标开始入队列
{
q->tail = 0;
}
++q->size;//队列size+1
return;
}
void SeqQueuePop(SeqQueue* q)
{
if(q == NULL)
{
//非法输入
return;
}
if(q->size == 0)
{
//空队列没法出队列
return;
}
++q->head;//将头元素的下标+1
if(q->head >= SeqQueueMaxSize)//如果头元素的下标已经超过了最大容量,就让下一个元素从0号下标开始出队列
{
q->head = 0;
}
--q->size;//队列size-1
return;
}
int SeqQueueFront(SeqQueue* q,SeqQueueType* value)
{
if(q == NULL || value == NULL)
{
//非法输入
return 0;
}
if(q->size == 0)
{
return 0;
}
*value = q->data[q->head];//将队列头元素的值赋给value
return 1;
}
#if 1
#include
#define TEST_HEADER printf("\n==========================%s===========================\n",__FUNCTION__);
void TestSeqQueue()
{
TEST_HEADER;
SeqQueue queue;
SeqQueueInit(&queue);
//首先入队列4个元素
SeqQueuePush(&queue,'a');
SeqQueuePush(&queue,'b');
SeqQueuePush(&queue,'c');
SeqQueuePush(&queue,'d');
SeqQueueType value;
int ret = SeqQueueFront(&queue,&value);
//因为队列遵循先进先出原则,所以第一个元素的值为a
printf("ret expected 1,actual %d\n",ret);
printf("value expected a,actual %c\n",value);
//出队列一个元素后,第一个元素值为b
SeqQueuePop(&queue);
ret = SeqQueueFront(&queue,&value);
printf("ret expected 1,actual %d\n",ret);
printf("value expected b,actual %c\n",value);
SeqQueuePop(&queue);
ret = SeqQueueFront(&queue,&value);
printf("ret expected 1,actual %d\n",ret);
printf("value expected c,actual %c\n",value);
SeqQueuePop(&queue);
ret = SeqQueueFront(&queue,&value);
printf("ret expected 1,actual %d\n",ret);
printf("value expected d,actual %c\n",value);
}
int main()
{
TestSeqQueue();
return 0;
}
#endif
.h文件
#pragma once
typedef char LinkType;
typedef struct LinkNode
{
LinkType data;
struct LinkNode* next;
}LinkNode;
typedef struct LinkQueue
{
LinkNode* head;
LinkNode* tail;
}LinkQueue;
void LinkQueueInit(LinkQueue* q);//队列的初始化
void LinkQueueDestroy(LinkQueue* q);//销毁队列
void LinkQueuePush(LinkQueue* q,LinkType value);//入队列
void LinkQueuePop(LinkQueue* q);//出队列
int LinkQueueFront(LinkQueue* q,LinkType* value);//取队首元素
.c文件
void LinkQueueInit(LinkQueue* q)
{
if(q == NULL)
{
//非法输入
return;
}
q->head = NULL;//设置头指针为空
q->tail = NULL;//设置为指针为空
return;
}
void LinkQueueDestroy(LinkQueue* q)//销毁队列
{
if(q == NULL)
{
//非法输入
return;
}
LinkNode* cur = q->head;
LinkNode* pre = cur;
while(cur != NULL)
{
pre = cur;
cur = cur->next;
free(pre);
}
q->head = q->tail = NULL;
return;
}
void DestroyLinkNode(LinkNode* to_delete)
{
if(to_delete == NULL)
{
return;
}
free(to_delete);//释放节点
to_delete = NULL;
return;
}
LinkNode* CreateLinkNode(LinkType value)
{
LinkNode* tmp = (LinkNode*)malloc(sizeof(LinkNode));
if(!tmp)//创建节点失败
{
printf("CreateLinkNode error!\n");
return NULL;
}
tmp->data = value;
tmp->next = NULL;
return tmp;
}
void LinkQueuePush(LinkQueue* q,LinkType value)
{
if(q == NULL)
{
//非法输入
return;
}
LinkNode* temp = CreateLinkNode(value);//创建一个新的节点temp
if(q->head == NULL)//如果队列中没有元素
{
q->head = temp;
q->tail = temp;
return;
}
//如果队列中有元素
q->tail->next = temp;//在原队列的尾部插入一个节点
q->tail = temp;//把尾指针后移
return;
}
void LinkQueuePop(LinkQueue* q)
{
if(q == NULL)
{
//非法输入
return;
}
LinkNode* to_delete = q->head;//to_delete指向队首节点
q->head = q->head->next;//更新头指针
DestroyLinkNode(to_delete);//销毁头结点
return;
}
int LinkQueueFront(LinkQueue* q,LinkType* value)
{
if(q == NULL )
{
//非法输入
return 0;
}
*value = q->head->data;//把队首元素的值赋给value
return 1;
}
#if 1
#define TEST_HEADER printf("\n======================%s========================\n",__FUNCTION__);
void LinkQueuePrintChar(LinkQueue* q,const char* msg)
{
printf("[%s]\n",msg);
LinkNode* cur = q->head;
for(;cur!= NULL;cur=cur->next)
{
printf("[%c][%p]<- ",cur->data,cur);
}
printf("NULL\n");
printf("\n");
}
void TestQueue()
{
TEST_HEADER;
LinkQueue queue;
LinkQueueInit(&queue);
LinkQueuePush(&queue,'a');
LinkQueuePush(&queue,'b');
LinkQueuePush(&queue,'c');
LinkQueuePush(&queue,'d');
LinkQueuePrintChar(&queue,"打印队列");
LinkType value;
int ret = LinkQueueFront(&queue,&value);
printf("ret expected 1,actual %d\n",ret);
printf("value expected a,actual %c\n",value);
LinkQueuePop(&queue);
ret = LinkQueueFront(&queue,&value);
printf("ret expected 1,actual %d\n",ret);
printf("value expected b,actual %c\n",value);
LinkQueuePop(&queue);
ret = LinkQueueFront(&queue,&value);
printf("ret expected 1,actual %d\n",ret);
printf("value expected c,actual %c\n",value);
LinkQueuePop(&queue);
ret = LinkQueueFront(&queue,&value);
printf("ret expected 1,actual %d\n",ret);
printf("value expected d,actual %c\n",value);
LinkQueue queue1;
LinkQueueInit(&queue1);
LinkQueuePush(&queue1,'a');
LinkQueuePush(&queue1,'b');
LinkQueuePush(&queue1,'c');
LinkQueuePush(&queue1,'d');
LinkQueuePrintChar(&queue1,"打印队列");
LinkQueueDestroy(&queue1);
LinkQueuePrintChar(&queue1,"打印队列");
}
int main()
{
TestQueue();
return 0;
}
#endif