队列是一种先进先出(FIFO)的特殊线性表。它只允许在表的一端进行插入,而在另一端删除元素。
在队列中,允许插入的一端叫做队尾,允许删除的一端则称为队头。
队列的基本操作也有三种,分别为:入队列、出队列、取队首元素。
seqqueue.h:
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>
typedef char SeqQueueType;
typedef struct SeqQueue{
SeqQueueType* data;
size_t head;
size_t tail;
size_t size;
size_t capacity;
}SeqQueue;
void SeqQueueInit(SeqQueue* s);
void SeqQueuePush(SeqQueue* s,SeqQueueType value);
void SeqQueuePop(SeqQueue* s);
int SeqQueueFront(SeqQueue* s,SeqQueueType* value);
void SeqQueueDestroy(SeqQueue* s);
void SeqQueuePrint(SeqQueue* s,const char* msg);
void SeqQueueResize(SeqQueue* s);
seqqueue.c:
#include "seqqueue.h"
void SeqQueueInit(SeqQueue* s){
if(s == NULL){
//非法输入
return;
}
s->head = 0;
s->tail = 0;
s->size = 0;
s->capacity = 1024;
s->data = (SeqQueueType*)malloc(s->capacity * sizeof(SeqQueueType));
return;
}
void SeqQueueDestroy(SeqQueue* s){
if(s == NULL){
return;
}
s->head = 0;
s->tail = 0;
s->size = 0;
s->capacity = 0;
free(s->data);
return;
}
void SeqQueuePrint(SeqQueue* s,const char* msg){
printf("[%s]\n",msg);
size_t i = 0;
for(;i < s->size;i++){
printf("[%c] ",s->data[i]);
}
printf("\n");
}
void SeqQueuePush(SeqQueue* s,SeqQueueType value){
if(s == NULL){
return;
}
if(s->size > s->capacity){
SeqQueueResize(s);
}
s->data[s->tail++] = value;
if(s->tail >= s->capacity){
s->tail = 0;
}
++s->size;
}
void SeqQueueResize(SeqQueue* s){
if(s == NULL){
return;
}
if(s->size < s->capacity){
return;
}
SeqQueueType* new_ptr = (SeqQueueType*)malloc(s->capacity * sizeof(SeqQueueType)*2+1);
size_t i = 0;
for(;i < s->size;i++){
new_ptr[i] = s->data[i];
}
free(s->data);
s->data = new_ptr;
}
void SeqQueuePop(SeqQueue* s){
if(s == NULL){
return;
}
if(s->size == 0){
return;
}
++s->head;
if(s->head >= s->capacity){
s->head = 0;
}
--s->size;
return;
}
int SeqQueueFront(SeqQueue* s,SeqQueueType* value){
if(s == NULL || value == NULL){
return 0;
}
if(s->size == 0){
return 0;
}
*value = s->data[s->head];
return 1;
}
test.c:
#include "seqqueue.h"
#define PRINT_HEAD printf("\n============%s============\n",__FUNCTION__)
void test(){
SeqQueue s;
SeqQueueInit(&s);
printf("size except 0,actual %d\n",s.size);
printf("capacity except 1024,actual %d\n",s.capacity);
printf("head except 0,actual %d\n",s.head);
printf("tail except 0,actual %d\n",s.tail);
SeqQueuePush(&s,'a');
SeqQueuePush(&s,'b');
SeqQueuePush(&s,'c');
SeqQueuePush(&s,'d');
SeqQueuePrint(&s,"入队列四个元素");
SeqQueueType value;
int ret = SeqQueueFront(&s,&value);
printf("ret except 1,actual %d\n",ret);
printf("front except a,actual %c\n",value);
SeqQueuePop(&s);
SeqQueuePrint(&s,"出队列一个元素");
ret = SeqQueueFront(&s,&value);
printf("ret except 1,actual %d\n",ret);
printf("front except b,actual %c\n",value);
SeqQueuePop(&s);
SeqQueuePrint(&s,"出队列两个元素");
ret = SeqQueueFront(&s,&value);
printf("ret except 1,actual %d\n",ret);
printf("front except c,actual %c\n",value);
SeqQueuePop(&s);
SeqQueuePrint(&s,"出队列三个元素");
ret = SeqQueueFront(&s,&value);
printf("ret except 1,actual %d\n",ret);
printf("front except d,actual %c\n",value);
SeqQueuePop(&s);
SeqQueuePrint(&s,"出队列四个元素");
ret = SeqQueueFront(&s,&value);
printf("ret except 0,actual %d\n",ret);
SeqQueuePop(&s);
SeqQueuePrint(&s,"尝试对空队列操作");
SeqQueuePush(&s,'a');
SeqQueuePush(&s,'b');
SeqQueuePush(&s,'c');
SeqQueuePush(&s,'d');
SeqQueuePrint(&s,"入队列四个元素");
SeqQueueDestroy(&s);
SeqQueuePrint(&s,"销毁队列");
}
int main(){
test();
}
结果演示: