queue.h
#ifndef __QUEUE_H__
#define __QUEUE_H__
#pragma once
#define _CRT_SECURE_NO_DEPRECATE 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
typedef struct QUEUE
{
void (*clear) (struct QUEUE*);//清空queue的队列,释放内存
void(*push)(struct QUEUE*, void*);//插入到队列的队尾
void (*pop)(struct QUEUE*);//删除queue的队头元素
void* (*front)(struct QUEUE*);// 返回队列的队头元素指针,但不删除该元素
void* (*back)(struct QUEUE*);// 返回队列的队尾元素指针,但不删除该元素
bool (*empty)(struct QUEUE*);// 当队列为空时返回true,否则返回false
int (*size)(struct QUEUE*);//返回队列中元素的个数
void* _date;//指向自定义数组类型
int _current;//当前元素个数
int _size;//元素最大个数
int _type;//类型占用字节数
}QUEUE;
void Queue_clear(struct QUEUE* que);//清空queue的队列,释放内存
void Queue_Push(QUEUE* que, void* x);//插入到队列的队尾
void Queue_pop(struct QUEUE* que);//删除queue的队头元素
void* Queue_front(struct QUEUE* que);// 返回队列的队头元素指针,但不删除该元素
void* Queue_back(struct QUEUE* que);// 返回队列的队尾元素指针,但不删除该元素
bool Queue_empty(struct QUEUE* que);//当队列为空时返回true,否则返回false
int Queue_size(struct QUEUE* que);//返回队列中元素的个数
//queue容器初始化函数
extern QUEUE* NewQueue(int sizen);
#endif
queue.c
#include"queue.h"
static struct List
{
void* date;
struct List* prev;//指向上一个
struct List* next;//指向下一个
};
//开辟新的节点
static List* open(QUEUE* que)
{
List* p = NULL;
if (que->_date == NULL&& que->_size==0)//无元素
{
p = malloc(sizeof(List));//新节点
que->_date = p;
if (que->_date == NULL)
{
perror("初始化queue失败");
exit(-1);
}
else
{
p->next = p;//头节点均指向自己
p->prev = p;
p->date = malloc(que->_type);//为节点数据开辟空间储存
if (p->date == NULL)
printf("开辟数据空间的时候失败\n");
que->_size++;
}
}
else
{
p = malloc(sizeof(List));//新节点
List* head = que->_date;//头节点
List* tail = head->prev;//原尾节点
p->next = head;//新节点下一个指向头节点
p->prev = tail;//新节点上一个指向原尾节点
head->prev = p;//头节点上一个指向新节点
tail->next = p;//原尾节点下一个指向新节点
p->date = malloc(que->_type);//为节点数据开辟空间储存
if (p->date == NULL)
printf("开辟数据空间的时候失败\n");
que->_size++;
}
return p;
}
void Queue_clear(QUEUE* que)//清空queue的队列,释放内存
{
if (que->_date != NULL && que->_size != 0)//无元素
{
List* p = que->_date;//开始指向头节点
List* pnext = NULL;
for (size_t i = 0; i < que->_size; i++)
{
pnext = p->next;//临时保存下一个节点地址
free(p->date);//释放节点的数据空间
free(p);//释放节点
p = pnext;//p指向下一个节点
}
que->_date = NULL;
que->_current = 0;
que->_size = 0;
}
}
void Queue_Push(QUEUE* que,void* x)//插入到队列的队尾
{
List* p = open(que);
memcpy(p->date, x, que->_type);
que->_current++;
}
void Queue_pop(struct QUEUE* que)//删除queue的队头元素
{
if (que->_current > 1)
{
List* head = que->_date;
List* next = head->next;
free(head->date);
free(head);
que->_date = next;
que->_current--;
}
else if (que->_current ==1)
{
List* head = que->_date;
free(head->date);
free(head);
que->_date = NULL;
que->_current--;
}
}
void* Queue_front(struct QUEUE* que)// 返回队列的队头元素指针,但不删除该元素
{
return ((List*)que->_date)->date;
}
void* Queue_back(struct QUEUE* que)// 返回队列的队尾元素指针,但不删除该元素
{
return ((List*)que->_date)->prev->date;
}
bool Queue_empty(struct QUEUE* que)//检测队内是否为空,空为真 O(1)
{
return !que->_current;
}
int Queue_size(struct QUEUE* que)//返回queue内元素的个数 O(1)
{
return que->_current;
}
//初始化函数
QUEUE* NewQueue(int sizen)
{
QUEUE* que = malloc(sizeof(QUEUE));
que->clear = Queue_clear;//清空queue的队列,释放内存
que->push = Queue_Push;//插入到队列的队尾
que->pop = Queue_pop;//删除queue的队头元素
que->front = Queue_front;//返回队列的队头元素指针,但不删除该元素
que->back = Queue_back; //返回队列的队尾元素指针,但不删除该元素
que->empty = Queue_empty;//当队列为空时返回true,否则返回false
que->size = Queue_size;//返回队列中元素的个数
que->_type = sizen;
que->_size = 0;
que->_date = NULL;
que->_current = 0;
return que;
}
test_queue.c
#include"queue.h"
typedef struct user
{
char name [20];
int age;
}user;
void int_test()
{
QUEUE* que=NewQueue(sizeof(int));//创建int类型队列
printf("int类型数据测试\n");
int num[] = {0,100,123,111,123,411};//创建要入队的数据
for (size_t i = 0; i < sizeof(num)/sizeof(num[0]); i++)
{
que->push(que, num+i);//入队
printf("%d\n", num[i]);
}
printf("下面为元素遍历\n");
while (!que->empty(que))
{
int n= *((int*)que->front(que));
printf("%d\n", n);
que->pop(que);
}
que->clear(que);//清空内存释放队列
free(que);
}
int main()
{
int_test();
return 0;
}
test_queue.c
#include"queue.h"
typedef struct user
{
char name [20];
int age;
}user;
void int_test()
{
QUEUE* que=NewQueue(sizeof(user));//创建int类型队列
printf("int类型数据测试\n");
int num[] = {0,100,123,111,123,411};//创建要入队的数据
for (size_t i = 0; i < sizeof(num)/sizeof(num[0]); i++)
{
user us;
us.age = num[i];
que->push(que, (void*)&us);//入队
printf("%d\n", num[i]);
}
printf("下面为元素遍历\n");
while (!que->empty(que))
{
user n= *((user*)que->front(que));
printf("%d\n", n.age);
que->pop(que);
}
que->clear(que);//清空内存释放队列
free(que);
}
int main()
{
int_test();
return 0;
}
gcc -o queue queue.c test_queue.c
int类型数据测试
0
100
123
111
123
411
下面为元素遍历
0
100
123
111
123
411