From 22c5df495d8a9aa071599a05a50dee5687171115 Mon Sep 17 00:00:00 2001 From: jf-home Date: Sat, 22 Jun 2024 01:37:27 +0800 Subject: [PATCH] =?UTF-8?q?FIFO=20=E9=98=9F=E5=88=97=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/queue.h | 44 ++++++ src/queue.c | 339 +++++++++++++++++++++++++++++++++------------- test/test.c | 29 +++- test/test.h | 21 +++ test/test_deque.c | 4 +- test/test_queue.c | 88 +++++++++++- test/test_stack.c | 6 +- 7 files changed, 427 insertions(+), 104 deletions(-) diff --git a/include/queue.h b/include/queue.h index c776f74..674c1f3 100644 --- a/include/queue.h +++ b/include/queue.h @@ -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_ diff --git a/src/queue.c b/src/queue.c index ad85744..6b9a89e 100644 --- a/src/queue.c +++ b/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; +} diff --git a/test/test.c b/test/test.c index 917a62e..4e860e4 100644 --- a/test/test.c +++ b/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(); } diff --git a/test/test.h b/test/test.h index 30575df..9a05ba2 100644 --- a/test/test.h +++ b/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); diff --git a/test/test_deque.c b/test/test_deque.c index 65d94fe..de5ba7e 100644 --- a/test/test_deque.c +++ b/test/test_deque.c @@ -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)) diff --git a/test/test_queue.c b/test/test_queue.c index 628f667..9c078a0 100644 --- a/test/test_queue.c +++ b/test/test_queue.c @@ -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 diff --git a/test/test_stack.c b/test/test_stack.c index 0d91ac2..48e80d8 100644 --- a/test/test_stack.c +++ b/test/test_stack.c @@ -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))