mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-05-18 03:51:35 +08:00
FIFO 队列实现
This commit is contained in:
parent
f7843c7226
commit
22c5df495d
@ -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_
|
||||
|
339
src/queue.c
339
src/queue.c
@ -4,135 +4,286 @@
|
||||
|
||||
bool queue_init(pqueue_t * head)
|
||||
{
|
||||
*head = (pqueue_t)malloc(sizeof(queue_t));
|
||||
if(*head == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
(*head)->front = NULL;
|
||||
(*head)->rear = NULL;
|
||||
(*head)->size = 0;
|
||||
return true;
|
||||
*head = (pqueue_t)malloc(sizeof(queue_t));
|
||||
ifqueue_head == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
queue_head)->front = NULL;
|
||||
queue_head)->rear = NULL;
|
||||
queue_head)->size = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void queue_destroy(pqueue_t * head)
|
||||
{
|
||||
if(*head != NULL)
|
||||
{
|
||||
queue_clear(*head);
|
||||
free(*head);
|
||||
*head = NULL;
|
||||
}
|
||||
ifqueue_head != NULL)
|
||||
{
|
||||
queue_clearqueue_head);
|
||||
freequeue_head);
|
||||
*head = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool queue_empty(pqueue_t head)
|
||||
{
|
||||
return (head == NULL || head->front == NULL || head->rear == NULL) ? true : false;
|
||||
return (head == NULL || head->front == NULL || head->rear == NULL) ? true : false;
|
||||
}
|
||||
|
||||
void queue_clear(pqueue_t head)
|
||||
{
|
||||
pqueue_node_t front_item;
|
||||
if(head != NULL)
|
||||
{
|
||||
front_item = head->front;
|
||||
while(head->front != NULL)
|
||||
{
|
||||
head->front = front_item->next;
|
||||
free(front_item);
|
||||
front_item = head->front;
|
||||
}
|
||||
head->rear = head->front;
|
||||
head->size = 0;
|
||||
}
|
||||
pqueue_node_t front_item;
|
||||
if(head != NULL)
|
||||
{
|
||||
front_item = head->front;
|
||||
while(head->front != NULL)
|
||||
{
|
||||
head->front = front_item->next;
|
||||
free(front_item);
|
||||
front_item = head->front;
|
||||
}
|
||||
head->rear = head->front;
|
||||
head->size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t queue_get_size(pqueue_t head)
|
||||
{
|
||||
return head->size;
|
||||
return head->size;
|
||||
}
|
||||
|
||||
bool queue_in(pqueue_t head, queue_data_t data)
|
||||
{
|
||||
pqueue_node_t new_item;
|
||||
if(head == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_item = (pqueue_node_t)malloc(sizeof(queue_node_t));
|
||||
if(new_item == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_item->data = data;
|
||||
new_item->next = NULL;
|
||||
if(head->front == NULL)
|
||||
{
|
||||
head->front = new_item;
|
||||
}
|
||||
// insert from tail
|
||||
if(head->rear != NULL)
|
||||
{
|
||||
head->rear->next = new_item;
|
||||
}
|
||||
head->rear = new_item;
|
||||
pqueue_node_t new_item;
|
||||
if(head == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_item = (pqueue_node_t)malloc(sizeof(queue_node_t));
|
||||
if(new_item == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_item->data = data;
|
||||
new_item->next = NULL;
|
||||
if(head->front == NULL)
|
||||
{
|
||||
head->front = new_item;
|
||||
}
|
||||
// insert from tail
|
||||
if(head->rear != NULL)
|
||||
{
|
||||
head->rear->next = new_item;
|
||||
}
|
||||
head->rear = new_item;
|
||||
|
||||
if (head->size < _UI32_MAX)
|
||||
{
|
||||
head->size++;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (head->size < _UI32_MAX)
|
||||
{
|
||||
head->size++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void queue_out(pqueue_t head, queue_data_t *data)
|
||||
{
|
||||
pqueue_node_t front_item;
|
||||
if(!queue_empty(head))
|
||||
{
|
||||
front_item = head->front;
|
||||
*data = front_item->data;
|
||||
pqueue_node_t front_item;
|
||||
if(!queue_empty(head))
|
||||
{
|
||||
front_item = head->front;
|
||||
*data = front_item->data;
|
||||
|
||||
// free the front item
|
||||
head->front = front_item->next;
|
||||
free(front_item);
|
||||
front_item = NULL;
|
||||
if (queue_get_size(head) == 1)
|
||||
{
|
||||
head->rear = NULL;
|
||||
}
|
||||
// free the front item
|
||||
head->front = front_item->next;
|
||||
free(front_item);
|
||||
front_item = NULL;
|
||||
if (queue_get_size(head) == 1)
|
||||
{
|
||||
head->rear = NULL;
|
||||
}
|
||||
|
||||
if (head > 0)
|
||||
{
|
||||
head->size--;
|
||||
}
|
||||
}
|
||||
if (head > 0)
|
||||
{
|
||||
head->size--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool queue_get_front(pqueue_t head, queue_data_t *data)
|
||||
{
|
||||
if(!queue_empty(head))
|
||||
{
|
||||
*data = head->front->data;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!queue_empty(head))
|
||||
{
|
||||
*data = head->front->data;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool queue_get_rear(pqueue_t head, queue_data_t *data)
|
||||
{
|
||||
if(!queue_empty(head))
|
||||
{
|
||||
*data = head->rear->data;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!queue_empty(head))
|
||||
{
|
||||
*data = head->rear->data;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
29
test/test.c
29
test/test.c
@ -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();
|
||||
|
||||
// queue_test();
|
||||
// deque_test();
|
||||
queue_test();
|
||||
|
||||
// tree_test();
|
||||
// rbtree_test();
|
||||
}
|
||||
|
21
test/test.h
21
test/test.h
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user