队列
基本操作:入队列、出队列、取队首元素;
基本特性:先进先出;
1.顺序队列:
实现顺序队列时,我们利用数组实现,定义了head,tail用来记录当前首元素和最后元素的下标。但是在删除时,因为队列要实现“先进先出”,所以进行头删。所以本来数组的下标为[0,MAXSIZE),原本的head应该为0,但头删之后就不为0。在tail等于或大于MASIZE值时,若head不为0,则可以从0再继续入队列,即只要tail没有追上head就可以继续向队列里放元素;同样地,在打印队列元素以检查操作是否正确时,也要考虑这个因素。
SeqQueue.h
#pragma once
#include <stdio.h>
#include <stddef.h>
#define SHOW_NAME printf("\n=================%s==================\n",__FUNCTION__);
#define MAX_SIZE 5
typedef char SeqQueueType;
typedef struct SeqQueue//整个队列的元素是从head到tail,
{ //由于出队是头删,所以前面可能会有空,所以当tail走到最后时,tail再指向0,只要size与MAX_SIZE不相等,就还有空间
SeqQueueType data[MAX_SIZE];
size_t head;//队列第一个元素下标
size_t tail;//队列最后一个元素的下标
size_t size;//用了多少个元素的空间
}SeqQueue;
SeqQueue.c
include "SeqQueue.h"
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 >= MAX_SIZE)//队列已满
return;
q->data[q->tail++] = value;
if(q->tail >= MAX_SIZE)//tail走到最后,就再指向头(只要size<MAX_SIZE)
q->tail = 0;
q->size++;
return;
}
void SeqQueuePop(SeqQueue* q)//出列队(头删)
{
if(q == NULL)//非法操作
return;
if(q->size == 0)//空队
return;
q->head++;
if(q->head >= MAX_SIZE)//别忘记!!!
q->head = 0;
q->size--;
return;
}
int SeqQueueGetFront(SeqQueue* q,SeqQueueType* value)//取队首元素
{
if(q == NULL)
return 0;
if(q->size == 0)
return 0;
*value = q->data[q->head];
return 1;
}
void SeqQueuePrint(SeqQueue* q,const char* msg)//打印
{
printf("[%s]\n",msg);
if(q == NULL)
return;
if(q->size == 0)//空队列
{
printf("空队\n");
return;
}
size_t i = q->head;
if(q->tail <= q->head)//tail在head前
{
for(; i<MAX_SIZE; ++i)
printf("[%c] ",q->data[i]);
for(i=0; i<q->tail; ++i)//q->tail指向最后一个元素的下一个位置
printf("[%c] ",q->data[i]);
}
else//tail在head后
{
for(i=q->head; i<q->tail; ++i)
printf("[%c] ",q->data[i]);
}
printf("\n");
return;
}
void TestInit()
{
SHOW_NAME;
SeqQueue q;
SeqQueueInit(&q);
printf("size: excpted is 0,actual is %d\n",q.size);
printf("head: excpted is 0,actual is %d\n",q.head);
printf("tail: excpted is 0,actual is %d\n",q.tail);
}
void TestDestroy()
{
SHOW_NAME;
SeqQueue q;
SeqQueueInit(&q);
SeqQueueDestroy(&q);
}
void TestPush()
{
SHOW_NAME;
SeqQueue q;
SeqQueueInit(&q);
SeqQueuePush(&q,'a');
SeqQueuePush(&q,'b');
SeqQueuePush(&q,'c');
SeqQueuePush(&q,'d');
SeqQueuePush(&q,'e');
SeqQueuePrint(&q,"入队五个元素");
}
void TestPop()
{
SHOW_NAME;
SeqQueue q;
SeqQueueInit(&q);
SeqQueuePush(&q,'a');
SeqQueuePush(&q,'b');
SeqQueuePush(&q,'c');
SeqQueuePush(&q,'d');
SeqQueuePush(&q,'e');
SeqQueuePrint(&q,"入队五个元素");
SeqQueuePop(&q);
SeqQueuePop(&q);
SeqQueuePop(&q);
SeqQueuePrint(&q,"出队三个元素");
SeqQueuePush(&q,'f');
SeqQueuePush(&q,'g');
SeqQueuePush(&q,'h');
SeqQueuePrint(&q,"入队三个元素");
SeqQueuePop(&q);
SeqQueuePop(&q);
SeqQueuePop(&q);
SeqQueuePrint(&q,"出队三个元素");
SeqQueuePop(&q);
SeqQueuePop(&q);
SeqQueuePrint(&q,"出队两个元素");
}
void TestGetFront()
{
SHOW_NAME;
SeqQueue q;
SeqQueueInit(&q);
SeqQueuePush(&q,'a');
SeqQueuePush(&q,'b');
SeqQueuePush(&q,'c');
SeqQueuePrint(&q,"入队三个元素");
int ret = 0;
SeqQueueType value;
ret = SeqQueueGetFront(&q,&value);
if(ret == 1)
printf("取得队首元素为 %c\n",value);
else
printf("未取得队首元素\n");
SeqQueuePop(&q);
SeqQueuePop(&q);
SeqQueuePop(&q);
SeqQueuePrint(&q,"出队三个元素");
ret = SeqQueueGetFront(&q,&value);
if(ret == 1)
printf("取得队首元素为 %c\n",value);
else
printf("未取得队首元素\n");
}
int main()
{
TestInit();
TestDestroy();
TestPush();
TestPop();
TestGetFront();
return 0;
}
2.链式队列:
类似单链表实现链式队列
LinkQueue.h
#pragma once
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#define SHOW_NAME printf("\n=================%s==================\n",__FUNCTION__);
typedef char LinkNodeType;
typedef struct LinkNode
{
LinkNodeType data;
struct LinkNode* next;
}LinkNode;
typedef struct LinkQueue//入队(尾插)、出队(头删)
{
LinkNode* head;
LinkNode* tail;
}LinkQueue;
LinkQueue.c
#include "LinkQueue.h"
void LinkQueueInit(LinkQueue* q)//初始化
{
if(q == NULL)//非法输入
return;
q->head = NULL;
q->tail =NULL;
}
void LinkQueueDestroy(LinkQueue* q)//销毁队列
{
if(q == NULL)
return;
LinkNode* cur = q->head;
while(cur != NULL)
{
LinkNode* to_delete = cur;
cur = cur->next;
free(to_delete);
}
q->head = q->tail = NULL;
return;
}
LinkNode* CreateNode(LinkNodeType value)//新建一个结点
{
LinkNode* new_node = (LinkNode*)malloc(sizeof(LinkNode));
new_node->data = value;
new_node->next = NULL;
return new_node;
}
void LinkQueuePush(LinkQueue* q,LinkNodeType value)//入队列(尾插)
{
if(q == NULL)//非法操作
return;
if(q->head==NULL)//空队列
{
q->head = q->tail = CreateNode(value);
return;
}
LinkNode* p = CreateNode(value);
q->tail->next = p;
q->tail = q->tail->next;
return;
}
void LinkQueuePop(LinkQueue* q)//出列队(头删)
{
if(q == NULL)//非法操作
return;
if(q->tail == NULL)//空队
return;
if(q->head->next == NULL)//只剩一个元素
{
q->head = q->tail = NULL;
return;
}
LinkNode* ret = q->head->next;
q->head = ret;
return;
}
int LinkQueueGetFront(LinkQueue* q,LinkNodeType* value)//取队首元素
{
if(q == NULL)
return 0;
if(q->tail == NULL)
return 0;
*value = q->head->data;
return 1;
}
void LinkQueuePrint(LinkQueue* q,const char* msg)//打印
{
printf("[%s]\n",msg);
LinkNode* cur = q->head;
for(; cur!=NULL; cur=cur->next)
{
printf("[%c] ",cur->data);
}
printf("\n");
return;
}
void TestInit()
{
SHOW_NAME;
LinkQueue q;
LinkQueueInit(&q);
}
void TestDestroy()
{
SHOW_NAME;
LinkQueue q;
LinkQueueInit(&q);
LinkQueueDestroy(&q);
}
void TestPush()
{
SHOW_NAME;
LinkQueue q;
LinkQueueInit(&q);
LinkQueuePush(&q,'a');
LinkQueuePush(&q,'b');
LinkQueuePush(&q,'c');
LinkQueuePush(&q,'d');
LinkQueuePush(&q,'e');
LinkQueuePrint(&q,"入队五个元素");
}
void TestPop()
{
SHOW_NAME;
LinkQueue q;
LinkQueueInit(&q);
LinkQueuePush(&q,'a');
LinkQueuePush(&q,'b');
LinkQueuePush(&q,'c');
LinkQueuePush(&q,'d');
LinkQueuePush(&q,'e');
LinkQueuePrint(&q,"入队五个元素");
LinkQueuePop(&q);
LinkQueuePop(&q);
LinkQueuePop(&q);
LinkQueuePrint(&q,"出队三个元素");
LinkQueuePush(&q,'f');
LinkQueuePush(&q,'g');
LinkQueuePush(&q,'h');
LinkQueuePrint(&q,"入队三个元素");
LinkQueuePop(&q);
LinkQueuePop(&q);
LinkQueuePop(&q);
LinkQueuePrint(&q,"出队三个元素");
LinkQueuePop(&q);
LinkQueuePop(&q);
LinkQueuePrint(&q,"出队两个元素");
}
void TestGetFront()
{
SHOW_NAME;
LinkQueue q;
LinkQueueInit(&q);
LinkQueuePush(&q,'a');
LinkQueuePush(&q,'b');
LinkQueuePush(&q,'c');
LinkQueuePrint(&q,"入队三个元素");
int ret;
LinkNodeType value;
ret = LinkQueueGetFront(&q,&value);
if(ret == 1)
printf("取得队首元素为 %c\n",value);
else
printf("未取得队首元素\n");
LinkQueuePop(&q);
LinkQueuePop(&q);
LinkQueuePop(&q);
LinkQueuePrint(&q,"出队三个元素");
ret = LinkQueueGetFront(&q,&value);
if(ret == 1)
printf("取得队首元素为 %c\n",value);
else
printf("未取得队首元素\n");
}
int main()
{
TestInit();
TestDestroy();
TestPush();
TestPop();
TestGetFront();
return 0;
}