FIFO 队列实现

This commit is contained in:
建峰 2024-06-22 01:37:27 +08:00
parent f7843c7226
commit 22c5df495d
7 changed files with 427 additions and 104 deletions

View File

@ -1,3 +1,13 @@
/**
* @file queue.h
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2024-06-22
*
* @copyright Copyright (c) 2024
*
*/
#ifndef _QUEUE_H_
#define _QUEUE_H_
@ -35,7 +45,41 @@ bool queue_get_rear(pqueue_t head, queue_data_t *data);
#endif
struct _queue_node
{
void *obj;
struct _queue_node * next;
};
struct _queue
{
struct _queue_node * _front;
struct _queue_node * _back;
uint32_t _obj_size; // 元素大小
uint32_t _size; // 栈大小
uint32_t _capacity; // 总容量
uint32_t _ratio; // 扩展比率
// kernel
bool (*push)(struct _queue* self, void* obj);
bool (*pop)(struct _queue* self, void* obj);
bool (*back)(struct _queue* self, void* obj);
bool (*front)(struct _queue* self, void* obj);
bool (*clear)(struct _queue* self);
bool (*empty)(struct _queue* self);
uint32_t (*size)(struct _queue* self);
// free
void (*destory)(struct _queue* self);
// print
void (*print)(struct _queue* self);
void (*print_obj)(void* obj);
};
bool queue_init(struct _queue * queue, uint32_t obj_size);
#endif // _QUEUE_H_

View File

@ -5,22 +5,22 @@
bool queue_init(pqueue_t * head)
{
*head = (pqueue_t)malloc(sizeof(queue_t));
if(*head == NULL)
ifqueue_head == NULL)
{
return false;
}
(*head)->front = NULL;
(*head)->rear = NULL;
(*head)->size = 0;
queue_head)->front = NULL;
queue_head)->rear = NULL;
queue_head)->size = 0;
return true;
}
void queue_destroy(pqueue_t * head)
{
if(*head != NULL)
ifqueue_head != NULL)
{
queue_clear(*head);
free(*head);
queue_clearqueue_head);
freequeue_head);
*head = NULL;
}
}
@ -136,3 +136,154 @@ bool queue_get_rear(pqueue_t head, queue_data_t *data)
}
#endif
bool queue_push(struct _queue* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
void * obj_new = malloc(self->_obj_size);
if (obj_new == NULL)
{
return false;
}
memmove(obj_new, obj, self->_obj_size);
struct _queue_node* node_new = (struct _queue_node*)malloc(sizeof(struct _queue_node));
if(node_new == NULL)
{
return false;
}
node_new->obj = obj_new;
node_new->next = NULL;
if(self->empty(self))
{
self->_front = node_new;
self->_back = node_new;
}
else
{
self->_back->next = node_new;
self->_back = node_new;
}
self->_size++;
return true;
}
bool queue_pop(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
struct _queue_node* node = self->_front;
if(obj != NULL)
{
memmove(obj, node->obj, self->_obj_size);
}
self->_front = node->next;
self->_size--;
free(node->obj);
free(node);
return true;
}
bool queue_back(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
memmove(obj, self->_back->obj, self->_obj_size);
return true;
}
bool queue_front(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
memmove(obj, self->_front->obj, self->_obj_size);
return true;
}
bool queue_clear(struct _queue* self)
{
assert(self != NULL);
struct _queue_node* node = self->_front;
struct _queue_node* next = NULL;
while (node)
{
next = node->next;
free(node->obj);
free(node);
node = next;
}
self->_front = NULL;
self->_back = NULL;
self->_size = 0;
return true;
}
bool queue_empty(struct _queue* self)
{
assert(self != NULL);
return !self->size(self);
}
uint32_t queue_size(struct _queue* self)
{
assert(self != NULL);
return self->_size;
}
void queue_destory(struct _queue* self)
{
assert(self != NULL);
self->clear(self);
}
void queue_print(struct _queue* self)
{
assert(self != NULL);
struct _queue_node * node = self->_front;
while (node)
{
self->print_obj(node->obj);
node = node->next;
}
}
bool queue_init(struct _queue * queue, uint32_t obj_size)
{
assert(queue != NULL);
assert(obj_size > 0);
// attribute init
queue->_size = 0;
queue->_obj_size = obj_size;
// queue->_capacity = 0;
// queue->_ratio = 0;
// function init
queue->push = queue_push;
queue->pop = queue_pop;
queue->back = queue_back;
queue->front = queue_front;
queue->clear = queue_clear;
queue->empty = queue_empty;
queue->size = queue_size;
queue->destory = queue_destory;
queue->print = queue_print;
// init front & back
queue->_front = NULL;
queue->_back = NULL;
}

View File

@ -1,16 +1,37 @@
#include "test.h"
void print_num(void* obj)
{
printf("(%2d ) ", *(int*)obj);
}
void print_struct(void* obj)
{
struct _student* student = (struct _student*)obj;
printf("(%4d:%-8s) ", student->id, student->name);
}
void print_char(void* obj)
{
printf("(%2c ) ", *(char*)obj);
}
void print_str(void* obj)
{
printf("(%s ) ", (char*)obj);
}
int main()
{
printf("----- unicstl -----\n");
printf("----- unicstl test -----\n");
// while (1)
{
// list_test();
// stack_test();
deque_test();
// deque_test();
queue_test();
// queue_test();
// tree_test();
// rbtree_test();
}

View File

@ -19,6 +19,27 @@
#endif
#endif
/**
* @brief test objects
*
*/
struct _student
{
char name[16];
int id;
};
void print_num(void* obj);
void print_char(void* obj);
void print_struct(void* obj);
void print_str(void* obj);
/**
* @brief test function
*
*/
void list_test(void);
void stack_test(void);
void deque_test(void);

View File

@ -74,7 +74,7 @@ static void deque_test_num(void)
}
else
{
printf("pop failed! because stack is empty\n");
printf("pop failed! because it is empty\n");
}
if (dq.empty(&dq))
@ -258,7 +258,7 @@ static void deque_test_struct(void)
}
else
{
printf("pop failed! because stack is empty\n");
printf("pop failed! because it is empty\n");
}
if (dq.empty(&dq))

View File

@ -1,4 +1,5 @@
#include "queue.h"
#include "test.h"
#if QUEUE_TEST == 1
@ -147,9 +148,94 @@ void queue_test(void)
#else
static void queue_test_num(void)
{
uint32_t i = 0;
int data[] = { 1,2,3,4,5,6,7,8,9,10 };
int temp = 0;
uint32_t len = sizeof(data) / sizeof(data[0]);
struct _queue queue;
queue_init(&queue, sizeof(int));
queue.print_obj = print_num;
printf("\n\n----- queue_test_num -----\n");
printf("----- after push-----\n");
for (i = 0; i < len; i++)
{
queue.push(&queue, &data[i]);
queue.front(&queue, &temp);
printf("front = ");
queue.print_obj(&temp);
queue.back(&queue, &temp);
printf("\tback = ");
queue.print_obj(&temp);
printf("\tsize = %2d\n", queue.size(&queue));
}
printf("----- print -----\n");
queue.print(&queue);
printf("\n");
queue.clear(&queue);
if (queue.empty(&queue))
{
printf("----- empty -----\n");
}
printf("----- push -----\n");
for (i = 0; i < len; i++)
{
queue.push(&queue, &data[i]);
}
printf("----- after pop -----\n");
for (i = 0; i < len + 1; i++)
{
if (true == queue.pop(&queue, &temp))
{
printf("pop = ");
queue.print_obj(&temp);
if (true == queue.front(&queue, &temp))
{
printf("front = ");
queue.print_obj(&temp);
}
if (queue.back(&queue, &temp))
{
printf("back = ");
queue.print_obj(&temp);
}
printf("size = %2d\n", queue.size(&queue));
}
else
{
printf("pop failed! because it is empty\n");
}
if (queue.empty(&queue))
{
printf("----- empty -----\n");
}
}
printf("----- print -----\n");
queue.print(&queue);
printf("\n");
queue.destory(&queue);
}
void queue_test(void)
{
queue_test_num();
}
#endif

View File

@ -54,7 +54,7 @@ static void stack_test_num(void)
}
else
{
printf("pop failed! because stack is empty\n");
printf("pop failed! because it is empty\n");
}
if (s.empty(&s))
@ -119,7 +119,7 @@ static void stack_test_char(void)
}
else
{
printf("pop failed! because stack is empty\n");
printf("pop failed! because it is empty\n");
}
if (s.empty(&s))
@ -207,7 +207,7 @@ static void stack_test_struct(void)
}
else
{
printf("pop failed! because stack is empty\n");
printf("pop failed! because it is empty\n");
}
if (s.empty(&s))