From a36bfd75077c81c1d79a1755aa780c3a1cd41b63 Mon Sep 17 00:00:00 2001 From: jf-home Date: Sun, 23 Jun 2024 14:43:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- include/common.h | 7 +- include/config.h | 30 - include/deque.h | 13 +- include/list.h | 12 +- include/queue.h | 32 - include/rbtree.h | 16 +- include/stack.h | 10 + include/tree.h | 12 +- include/unicstl.h | 18 +- src/deque.c | 11 +- src/list.c | 11 +- src/queue.c | 148 +--- src/rbtree.c | 1870 ++++++++++++++++++++--------------------- src/stack.c | 11 +- src/tree.c | 15 +- src/unicstl.c | 11 +- test/test.c | 6 +- test/test.h | 6 +- test/test_deque.c | 25 +- test/test_list.c | 2 +- test/test_queue.c | 164 +--- 22 files changed, 1093 insertions(+), 1340 deletions(-) delete mode 100644 include/config.h diff --git a/.vscode/settings.json b/.vscode/settings.json index f9a2d83..5d123be 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,7 @@ "list.h": "c", "stdio.h": "c", "tree.h": "c", - "deque.h": "c" + "deque.h": "c", + "config.h": "c" } } \ No newline at end of file diff --git a/include/common.h b/include/common.h index 30767c4..020475d 100644 --- a/include/common.h +++ b/include/common.h @@ -1,6 +1,6 @@ -#ifndef _DEMO_H_ -#define _DEMO_H_ +#ifndef _COMMON_H_ +#define _COMMON_H_ #include #include @@ -9,9 +9,6 @@ #include #include -#include "config.h" - - #if RBTREE == 1 #include "rbtree.h" typedef prbtree_node_t stack_data_t; diff --git a/include/config.h b/include/config.h deleted file mode 100644 index c3252e6..0000000 --- a/include/config.h +++ /dev/null @@ -1,30 +0,0 @@ - -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -#include -#include -#include -#include - - -// optional -#define RBTREE 0 -#define AVLTREE 0 -#define RAVLTREE 0 // avl tree by recursion -#define QUEUE 0 -#define STACK 1 -#define LIST 1 - - -// -------------------------------------------------- -#if RBTREE == 1 && AVLTREE == 1 -#error "Rbtree and avltree cannot coexist" -#endif - -#if RAVLTREE == 1 && AVLTREE == 1 -#error "Recursive avltree and avltree cannot coexist" -#endif - -#endif // _CONFIG_H_ - diff --git a/include/deque.h b/include/deque.h index 17f48b5..bcbb6f0 100644 --- a/include/deque.h +++ b/include/deque.h @@ -1,8 +1,17 @@ - +/** + * @file deque.h + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #ifndef _DEQUE_H_ #define _DEQUE_H_ -#include "unicstl.h" +#include "common.h" struct _deque_node { diff --git a/include/list.h b/include/list.h index 1ba0f1f..26e4a54 100644 --- a/include/list.h +++ b/include/list.h @@ -1,7 +1,17 @@ +/** + * @file list.h + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #ifndef _LIST_H_ #define _LIST_H_ -#include "unicstl.h" +#include "common.h" struct _list { diff --git a/include/queue.h b/include/queue.h index 8fe5ac9..010e2b1 100644 --- a/include/queue.h +++ b/include/queue.h @@ -13,38 +13,6 @@ #include "common.h" -#if QUEUE == 1 -// typedef int queue_data_t; - -// node of queue -typedef struct _queue_node_t -{ - queue_data_t data; - struct _queue_node_t * next; -} queue_node_t, *pqueue_node_t; - -// queue -typedef struct _queue_t -{ - struct _queue_node_t * front; - struct _queue_node_t * rear; - uint32_t size; -}queue_t,*pqueue_t; - - -bool queue_init(pqueue_t * head); -void queue_destroy(pqueue_t * head); -bool queue_empty(pqueue_t head); -void queue_clear(pqueue_t head); -uint32_t queue_get_size(pqueue_t head); - -bool queue_in(pqueue_t head, queue_data_t data); -void queue_out(pqueue_t head, queue_data_t *data); -bool queue_get_front(pqueue_t head, queue_data_t *data); -bool queue_get_rear(pqueue_t head, queue_data_t *data); - -#endif - struct _queue_node { void *obj; diff --git a/include/rbtree.h b/include/rbtree.h index 889f70b..ed9fe06 100644 --- a/include/rbtree.h +++ b/include/rbtree.h @@ -2,24 +2,24 @@ #ifndef _RBTREE_H_ #define _RBTREE_H_ -#include "config.h" +#include "common.h" #if RBTREE == 1 typedef int rbtree_data_t; typedef struct _rbtree_node_t { - rbtree_data_t data; - struct _rbtree_node_t * left; - struct _rbtree_node_t * right; - struct _rbtree_node_t * parent; - uint32_t color; + rbtree_data_t data; + struct _rbtree_node_t * left; + struct _rbtree_node_t * right; + struct _rbtree_node_t * parent; + uint32_t color; }rbtree_node_t, *prbtree_node_t; typedef struct _rbtree_t { - struct _rbtree_node_t * tree; - uint32_t size; + struct _rbtree_node_t * tree; + uint32_t size; }rbtree_t, *prbtree_t; diff --git a/include/stack.h b/include/stack.h index 527f36d..68bfcac 100644 --- a/include/stack.h +++ b/include/stack.h @@ -1,3 +1,13 @@ +/** + * @file stack.h + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #ifndef _STACK_H_ #define _STACK_H_ diff --git a/include/tree.h b/include/tree.h index ba17541..8962f4b 100644 --- a/include/tree.h +++ b/include/tree.h @@ -1,3 +1,13 @@ +/** + * @file tree.h + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #ifndef _TREE_H_ #define _TREE_H_ @@ -77,7 +87,7 @@ struct _tree_node uint32_t color; }; }; -typedef struct _tree_node * tree_node_t; +typedef struct _tree_node* tree_node_t; struct _tree { diff --git a/include/unicstl.h b/include/unicstl.h index d6fb617..00c9819 100644 --- a/include/unicstl.h +++ b/include/unicstl.h @@ -1,14 +1,16 @@ - +/** + * @file unicstl.h + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #ifndef _DEMO_H_ #define _DEMO_H_ -#include -#include -#include -#include -#include -#include - #include "list.h" #include "stack.h" #include "queue.h" diff --git a/src/deque.c b/src/deque.c index d41ad80..0d5cb22 100644 --- a/src/deque.c +++ b/src/deque.c @@ -1,4 +1,13 @@ - +/** + * @file deque.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #include "deque.h" bool deque_push_back(struct _deque* self, void* obj) diff --git a/src/list.c b/src/list.c index 80f0b94..b62a90b 100644 --- a/src/list.c +++ b/src/list.c @@ -1,4 +1,13 @@ - +/** + * @file list.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #include "list.h" bool list_append(struct _list* self, void* obj) diff --git a/src/queue.c b/src/queue.c index e38a2cb..04709c3 100644 --- a/src/queue.c +++ b/src/queue.c @@ -1,142 +1,14 @@ - +/** + * @file queue.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #include "queue.h" -#if QUEUE == 1 - -bool queue_init(pqueue_t * head) -{ - *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) -{ - 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; -} - -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; - } -} - -uint32_t queue_get_size(pqueue_t head) -{ - 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; - - 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; - - // 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--; - } - } -} - -bool queue_get_front(pqueue_t head, queue_data_t *data) -{ - 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; - } -} - -#endif - bool queue_push(struct _queue* self, void* obj) { diff --git a/src/rbtree.c b/src/rbtree.c index 80eb966..9ff6eae 100644 --- a/src/rbtree.c +++ b/src/rbtree.c @@ -31,9 +31,9 @@ #define RBT_VISIT_LEFT(x) (RBT_COLOR(x) |= RBT_VISIT_FLAG_LEFT) #define RBT_VISIT_RIGHT(x) (RBT_COLOR(x) |= RBT_VISIT_FLAG_RIGHT) #define RBT_IS_VISITED_LEFT(x) (((RBT_COLOR(x) & RBT_VISIT_FLAG_LEFT) == RBT_VISIT_FLAG_LEFT)?\ - true:false) + true:false) #define RBT_IS_VISITED_RIGHT(x) (((RBT_COLOR(x) & RBT_VISIT_FLAG_RIGHT) == RBT_VISIT_FLAG_RIGHT)?\ - true:false) + true:false) @@ -46,789 +46,789 @@ static bool rbtree_delete_fixup(prbtree_t head, prbtree_node_t tree); bool rbtree_init(prbtree_t *head) { - *head = (prbtree_t)malloc(sizeof(rbtree_t)); - if (*head == NULL) - { - return false; - } - (*head)->tree = NULL; - (*head)->size = 0; - return true; + *head = (prbtree_t)malloc(sizeof(rbtree_t)); + if (*head == NULL) + { + return false; + } + (*head)->tree = NULL; + (*head)->size = 0; + return true; } void rbtree_destroy(prbtree_t * head) { - if (*head != NULL) - { - rbtree_clear(*head); - free(*head); - *head = NULL; - } + if (*head != NULL) + { + rbtree_clear(*head); + free(*head); + *head = NULL; + } } bool rbtree_empty(prbtree_t head) { - return ((head == NULL) || (head->tree == NULL)) ? true : false; + return ((head == NULL) || (head->tree == NULL)) ? true : false; } void rbtree_clear(prbtree_t head) { - pqueue_t queue; - prbtree_node_t root; - prbtree_node_t tree_node; + pqueue_t queue; + prbtree_node_t root; + prbtree_node_t tree_node; - if ((head == NULL) || head->tree == NULL) - { - return; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return; + } + root = head->tree; - queue_init(&queue); - queue_in(queue, root); + queue_init(&queue); + queue_in(queue, root); - while (!queue_empty(queue)) - { - queue_out(queue, &tree_node); - if (tree_node->left != NULL) - { - queue_in(queue, tree_node->left); - } - if (tree_node->right != NULL) - { - queue_in(queue, tree_node->right); - } + while (!queue_empty(queue)) + { + queue_out(queue, &tree_node); + if (tree_node->left != NULL) + { + queue_in(queue, tree_node->left); + } + if (tree_node->right != NULL) + { + queue_in(queue, tree_node->right); + } - free(tree_node); - tree_node = NULL; - } + free(tree_node); + tree_node = NULL; + } - queue_destroy(&queue); + queue_destroy(&queue); - head->tree = NULL; - head->size = 0; + head->tree = NULL; + head->size = 0; } uint32_t rbtree_get_size(prbtree_t head) { - return head->size; + return head->size; } static prbtree_node_t rbtree_find(prbtree_t head, rbtree_data_t data) { - prbtree_node_t root; + prbtree_node_t root; - if ((head == NULL) || head->tree == NULL) - { - return NULL; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return NULL; + } + root = head->tree; - while (root != NULL) - { - if (data < root->data) - { - if (root->left != NULL) - { - root = root->left; - } - else - { - return root; - } - } - else if (data > root->data) - { - if (root->right != NULL) - { - root = root->right; - } - else - { - return root; - } - } - else - { - // == - return root; - } - } + while (root != NULL) + { + if (data < root->data) + { + if (root->left != NULL) + { + root = root->left; + } + else + { + return root; + } + } + else if (data > root->data) + { + if (root->right != NULL) + { + root = root->right; + } + else + { + return root; + } + } + else + { + // == + return root; + } + } - return root; + return root; } static prbtree_node_t get_parent_node(prbtree_node_t tree) { - if (tree == NULL) - { - return NULL; - } - return tree->parent; + if (tree == NULL) + { + return NULL; + } + return tree->parent; } bool rbtree_insert(prbtree_t head, rbtree_data_t data) { - prbtree_node_t tree_node; - prbtree_node_t new_node; + prbtree_node_t tree_node; + prbtree_node_t new_node; - if (head == NULL) - { - return false; - } + if (head == NULL) + { + return false; + } - // no root of tree - if (head->tree == NULL) - { - new_node = (prbtree_node_t)malloc(sizeof(rbtree_node_t)); - if (new_node == NULL) - { - return false; - } - new_node->data = data; - new_node->left = NULL; - new_node->right = NULL; - new_node->parent = NULL; // the parent of root is NULL - RBT_COLOR_INIT(new_node); + // no root of tree + if (head->tree == NULL) + { + new_node = (prbtree_node_t)malloc(sizeof(rbtree_node_t)); + if (new_node == NULL) + { + return false; + } + new_node->data = data; + new_node->left = NULL; + new_node->right = NULL; + new_node->parent = NULL; // the parent of root is NULL + RBT_COLOR_INIT(new_node); - head->tree = new_node; - } - else - { - tree_node = rbtree_find(head, data); - if (data < tree_node->data) - { - new_node = (prbtree_node_t)malloc(sizeof(rbtree_node_t)); - if (new_node == NULL) - { - return false; - } - new_node->data = data; - new_node->left = NULL; - new_node->right = NULL; - new_node->parent = tree_node; - RBT_COLOR_INIT(new_node); + head->tree = new_node; + } + else + { + tree_node = rbtree_find(head, data); + if (data < tree_node->data) + { + new_node = (prbtree_node_t)malloc(sizeof(rbtree_node_t)); + if (new_node == NULL) + { + return false; + } + new_node->data = data; + new_node->left = NULL; + new_node->right = NULL; + new_node->parent = tree_node; + RBT_COLOR_INIT(new_node); - tree_node->left = new_node; - } - else if(data > tree_node->data) - { - new_node = (prbtree_node_t)malloc(sizeof(rbtree_node_t)); - if (new_node == NULL) - { - return false; - } - new_node->data = data; - new_node->left = NULL; - new_node->right = NULL; - new_node->parent = tree_node; - RBT_COLOR_INIT(new_node); + tree_node->left = new_node; + } + else if(data > tree_node->data) + { + new_node = (prbtree_node_t)malloc(sizeof(rbtree_node_t)); + if (new_node == NULL) + { + return false; + } + new_node->data = data; + new_node->left = NULL; + new_node->right = NULL; + new_node->parent = tree_node; + RBT_COLOR_INIT(new_node); - tree_node->right = new_node; - } - else - { - // 若key相等,正常来说应该替换value值。 - // 这里的代码仅仅是个工程简单工程示例, - // data区就一个数据,因此此处直接忽略。 - return true; - } - } + tree_node->right = new_node; + } + else + { + // 若key相等,正常来说应该替换value值。 + // 这里的代码仅仅是个工程简单工程示例, + // data区就一个数据,因此此处直接忽略。 + return true; + } + } - rbtree_insert_fixup(head, new_node); + rbtree_insert_fixup(head, new_node); - if (head->size < _UI32_MAX) - { - head->size++; - } - return true; + if (head->size < _UI32_MAX) + { + head->size++; + } + return true; } static prbtree_node_t rbtree_turn_left(prbtree_node_t tree) { - // 以当前节点为中心旋转 - // 注意父节点并不动,只是为了连接新的子节点 - // - prbtree_node_t node_n; // 当前节点 - prbtree_node_t node_nr; // 当前节点的右子节点 - prbtree_node_t node_p; // 当前节点的父节点 + // 以当前节点为中心旋转 + // 注意父节点并不动,只是为了连接新的子节点 + // + prbtree_node_t node_n; // 当前节点 + prbtree_node_t node_nr; // 当前节点的右子节点 + prbtree_node_t node_p; // 当前节点的父节点 - if (tree == NULL) - { - return NULL; - } - node_n = tree; - node_nr = node_n->right; - node_p = node_n->parent; + if (tree == NULL) + { + return NULL; + } + node_n = tree; + node_nr = node_n->right; + node_p = node_n->parent; - // 1. 更新node_p子节点 - if (node_p != NULL) - { - // not root of tree - if (node_p->left == node_n) - { - node_p->left = node_nr; - } - else - { - node_p->right = node_nr; - } - } - node_nr->parent = node_p; + // 1. 更新node_p子节点 + if (node_p != NULL) + { + // not root of tree + if (node_p->left == node_n) + { + node_p->left = node_nr; + } + else + { + node_p->right = node_nr; + } + } + node_nr->parent = node_p; - // 2. 旋转 - node_n->parent = node_nr; // 不能直接node_p=node_nr,原因你懂的 - node_n->right = node_nr->left; - node_nr->left = node_n; - if (node_n->right != NULL) - { - node_n->right->parent = node_n; - } + // 2. 旋转 + node_n->parent = node_nr; // 不能直接node_p=node_nr,原因你懂的 + node_n->right = node_nr->left; + node_nr->left = node_n; + if (node_n->right != NULL) + { + node_n->right->parent = node_n; + } - // 3. 返回新的节点 - return node_nr; + // 3. 返回新的节点 + return node_nr; } static prbtree_node_t rbtree_turn_right(prbtree_node_t tree) { - // 以当前节点为中心旋转 - // 注意父节点并不动,只是为了连接新的子节点 - // - prbtree_node_t node_n; // 当前节点 - prbtree_node_t node_nl; // 当前节点的左子节点 - prbtree_node_t node_p; // 当前节点的父节点 + // 以当前节点为中心旋转 + // 注意父节点并不动,只是为了连接新的子节点 + // + prbtree_node_t node_n; // 当前节点 + prbtree_node_t node_nl; // 当前节点的左子节点 + prbtree_node_t node_p; // 当前节点的父节点 - if (tree == NULL) - { - return NULL; - } - node_n = tree; - node_nl = node_n->left; - node_p = node_n->parent; + if (tree == NULL) + { + return NULL; + } + node_n = tree; + node_nl = node_n->left; + node_p = node_n->parent; - // 1. 更新node_p子节点 - if (node_p != NULL) - { - // not node_n - if (node_p->left == node_n) - { - node_p->left = node_nl; - } - else - { - node_p->right = node_nl; - } - } - node_nl->parent = node_p; + // 1. 更新node_p子节点 + if (node_p != NULL) + { + // not node_n + if (node_p->left == node_n) + { + node_p->left = node_nl; + } + else + { + node_p->right = node_nl; + } + } + node_nl->parent = node_p; - // 2. 旋转 - node_n->parent = node_nl; // 不能直接node_p=node_nl,原因你懂的 - node_n->left = node_nl->right; - node_nl->right = node_n; - if (node_n->left != NULL) - { - node_n->left->parent = node_n; - } + // 2. 旋转 + node_n->parent = node_nl; // 不能直接node_p=node_nl,原因你懂的 + node_n->left = node_nl->right; + node_nl->right = node_n; + if (node_n->left != NULL) + { + node_n->left->parent = node_n; + } - // 3. 返回新的节点 - return node_nl; + // 3. 返回新的节点 + return node_nl; } static bool rbtree_insert_fixup(prbtree_t head, prbtree_node_t tree) { - prbtree_node_t father, grandfather, uncle; - if ((head == NULL) || head->tree == NULL) - { - return false; - } + prbtree_node_t father, grandfather, uncle; + if ((head == NULL) || head->tree == NULL) + { + return false; + } - if (tree == NULL) - { - return false; - } + if (tree == NULL) + { + return false; + } - // --------------------------------------- - // case1.根节点不存在,则直接插入黑色节点 - // case2.父节点为黑,插入红色节点皆可 - // (以上两种情况,要结合insert函数理解) - // case3.主要分为三种情况考虑,如下 - // (左右对称,理解了左三,则右三也就不难了) - // ---------------------------------------- - while (tree->parent != NULL && RBT_IS_RED(tree->parent)) - { - father = get_parent_node(tree); - grandfather = get_parent_node(father); - - if (father == grandfather->left) - { - uncle = grandfather->right; - if (uncle != NULL && RBT_IS_RED(uncle)) - { - RBT_SET_BLACK(father); - RBT_SET_BLACK(uncle); - RBT_SET_RED(grandfather); - tree = grandfather; - } - else - { - if (tree == father->right) - { - tree = rbtree_turn_left(father); - RBT_SET_BLACK(tree); - } - else - { - RBT_SET_BLACK(father); - } - RBT_SET_RED(grandfather); - tree = rbtree_turn_right(grandfather); - break; - } - } - else - { - uncle = grandfather->left; - if (uncle != NULL && RBT_IS_RED(uncle)) - { - RBT_SET_BLACK(father); - RBT_SET_BLACK(uncle); - RBT_SET_RED(grandfather); - tree = grandfather; - } - else - { - if (tree == father->left) - { - tree = rbtree_turn_right(father); - RBT_SET_BLACK(tree); - } - else - { - RBT_SET_BLACK(father); - } - RBT_SET_RED(grandfather); - tree = rbtree_turn_left(grandfather); - break; - } - } - } + // --------------------------------------- + // case1.根节点不存在,则直接插入黑色节点 + // case2.父节点为黑,插入红色节点皆可 + // (以上两种情况,要结合insert函数理解) + // case3.主要分为三种情况考虑,如下 + // (左右对称,理解了左三,则右三也就不难了) + // ---------------------------------------- + while (tree->parent != NULL && RBT_IS_RED(tree->parent)) + { + father = get_parent_node(tree); + grandfather = get_parent_node(father); + + if (father == grandfather->left) + { + uncle = grandfather->right; + if (uncle != NULL && RBT_IS_RED(uncle)) + { + RBT_SET_BLACK(father); + RBT_SET_BLACK(uncle); + RBT_SET_RED(grandfather); + tree = grandfather; + } + else + { + if (tree == father->right) + { + tree = rbtree_turn_left(father); + RBT_SET_BLACK(tree); + } + else + { + RBT_SET_BLACK(father); + } + RBT_SET_RED(grandfather); + tree = rbtree_turn_right(grandfather); + break; + } + } + else + { + uncle = grandfather->left; + if (uncle != NULL && RBT_IS_RED(uncle)) + { + RBT_SET_BLACK(father); + RBT_SET_BLACK(uncle); + RBT_SET_RED(grandfather); + tree = grandfather; + } + else + { + if (tree == father->left) + { + tree = rbtree_turn_right(father); + RBT_SET_BLACK(tree); + } + else + { + RBT_SET_BLACK(father); + } + RBT_SET_RED(grandfather); + tree = rbtree_turn_left(grandfather); + break; + } + } + } - if (tree->parent == NULL) - { - head->tree = tree; - RBT_SET_BLACK(head->tree); - } + if (tree->parent == NULL) + { + head->tree = tree; + RBT_SET_BLACK(head->tree); + } - return true; + return true; } static prbtree_node_t tree_get_node_min(prbtree_node_t tree) { - while (tree != NULL) - { - if (tree->left != NULL) - { - tree = tree->left; - } - else - { - return tree; - } - } - return tree; + while (tree != NULL) + { + if (tree->left != NULL) + { + tree = tree->left; + } + else + { + return tree; + } + } + return tree; } bool rbtree_delete(prbtree_t head, rbtree_data_t data) { - prbtree_node_t tree_node; //当前本该删除的节点 - prbtree_node_t tree_node_del; //实际上被删除的节点 + prbtree_node_t tree_node; //当前本该删除的节点 + prbtree_node_t tree_node_del; //实际上被删除的节点 - if ((head == NULL) || head->tree == NULL) - { - return false; - } - - tree_node = rbtree_find(head, data); - if (tree_node == NULL) - { - return false; - } + if ((head == NULL) || head->tree == NULL) + { + return false; + } + + tree_node = rbtree_find(head, data); + if (tree_node == NULL) + { + return false; + } - if (tree_node->data != data) - { - // 没有找到该参数 - return false; - } + if (tree_node->data != data) + { + // 没有找到该参数 + return false; + } - if (tree_node->left == NULL && tree_node->right == NULL) - { - tree_node_del = tree_node; - } - else if (tree_node->left != NULL && tree_node->right == NULL) - { - tree_node_del = tree_node->left; - tree_node->data = tree_node_del->data; - } - else if (tree_node->left == NULL && tree_node->right != NULL) - { - tree_node_del = tree_node->right; - tree_node->data = tree_node_del->data; - } - else - { - // 双子都在,则查找后继节点 - tree_node_del = tree_get_node_min(tree_node->right); + if (tree_node->left == NULL && tree_node->right == NULL) + { + tree_node_del = tree_node; + } + else if (tree_node->left != NULL && tree_node->right == NULL) + { + tree_node_del = tree_node->left; + tree_node->data = tree_node_del->data; + } + else if (tree_node->left == NULL && tree_node->right != NULL) + { + tree_node_del = tree_node->right; + tree_node->data = tree_node_del->data; + } + else + { + // 双子都在,则查找后继节点 + tree_node_del = tree_get_node_min(tree_node->right); - tree_node->data = tree_node_del->data; - if (tree_node_del->right != NULL) - { - // 必红 - tree_node_del->data = tree_node_del->right->data; - tree_node_del = tree_node_del->right; - } - } + tree_node->data = tree_node_del->data; + if (tree_node_del->right != NULL) + { + // 必红 + tree_node_del->data = tree_node_del->right->data; + tree_node_del = tree_node_del->right; + } + } - if (RBT_IS_BLACK(tree_node_del)) - { - rbtree_delete_fixup(head, tree_node_del); - } + if (RBT_IS_BLACK(tree_node_del)) + { + rbtree_delete_fixup(head, tree_node_del); + } - // 从tree中删除 - if (tree_node_del->parent != NULL) - { - if (tree_node_del == tree_node_del->parent->left) - { - tree_node_del->parent->left = NULL; - } - else - { - tree_node_del->parent->right = NULL; - } - } - else - { - // 若为根节点 - head->tree = NULL; - } - // 释放内存 - free(tree_node_del); + // 从tree中删除 + if (tree_node_del->parent != NULL) + { + if (tree_node_del == tree_node_del->parent->left) + { + tree_node_del->parent->left = NULL; + } + else + { + tree_node_del->parent->right = NULL; + } + } + else + { + // 若为根节点 + head->tree = NULL; + } + // 释放内存 + free(tree_node_del); - if (head->size > 0) - { - head->size--; - } - return true; + if (head->size > 0) + { + head->size--; + } + return true; } static bool rbtree_delete_fixup(prbtree_t head, prbtree_node_t tree) { - prbtree_node_t node_temp = NULL; - prbtree_node_t father, brother; - if ((head == NULL) || head->tree == NULL) - { - return false; - } + prbtree_node_t node_temp = NULL; + prbtree_node_t father, brother; + if ((head == NULL) || head->tree == NULL) + { + return false; + } - while ((tree->parent != NULL) && RBT_IS_BLACK(tree)) - { - father = get_parent_node(tree); - if (tree == father->left) - { - brother = father->right; - if (RBT_IS_RED(brother)) - { - // 根据rbtree性质,父节点必定为黑, - // 红brother的子节点双黑或者双空 - // case 5 - RBT_SET_BLACK(brother); - RBT_SET_RED(father); - node_temp = rbtree_turn_left(father); - // 节点未删除时平衡,但是删除之后又不平衡了 - // 因此需要继续判断 - } - else if(brother->right != NULL && RBT_IS_RED(brother->right)) - { - // 黑bother存在right节点,并且为红色的情况 - // 父节点颜色未知 - // case 1 (仅右子红)和 case 3(双子红) 本质上一样 - RBT_COLOR_ASSIGN(brother,father); //color(f) -> color(b) - RBT_SET_BLACK(father); - RBT_SET_BLACK(brother->right); - tree = rbtree_turn_left(father); - // 删除节点之后,肯定平衡了,因此退出 - // 另外,翻转之后,若刚好是根节点。则赋值给tree - // 方便循环外面判断 - break; - } - else if(brother->left != NULL && RBT_IS_RED(brother->left)) - { - // 黑bother仅有left节点,且left为红色,(且rigth不红的情况) - // 父节点颜色未知 - // case 2 - // 注意:这样写代码的话,则必须在case2前先判断case1/case3 - RBT_SET_RED(brother); - RBT_SET_BLACK(brother->left); - node_temp = rbtree_turn_right(brother); - // 随后转化为了case 1 - } - else - { - // 黑brother的子节点为双空或双黑 - // case 4 - if(RBT_IS_BLACK(father)) - { - // 若父节点为黑,则将brother染为红色, - // 但是总体是少了一黑,因此以父节点为tree向上递归 - RBT_SET_RED(brother); - tree = father; - } - else - { - // brother双子空,则表示brother和被删除的节点平衡 - // 因此直接转换颜色即可 - RBT_SET_RED(brother); - RBT_SET_BLACK(father); - // 删除节点之后,肯定平衡了,因此退出 - break; - } - } - } - else - { - brother = father->left; - if (RBT_IS_RED(brother)) - { - // 根据rbtree性质,父节点必定为黑, - // 红brother的子节点双黑或者双空 - // case 5 - RBT_SET_BLACK(brother); - RBT_SET_RED(father); - node_temp = rbtree_turn_right(father); - // 节点未删除时平衡,但是删除之后又不平衡了 - // 因此需要继续判断 - } - else if (brother->left != NULL && RBT_IS_RED(brother->left)) - { - // 黑bother存在left节点,并且为红色的情况 - // 父节点颜色未知 - // case 1 (仅右子红)和 case 3(双子红) 本质上一样 - RBT_COLOR_ASSIGN(brother,father); - RBT_SET_BLACK(father); - RBT_SET_BLACK(brother->left); - tree = rbtree_turn_right(father); - // 删除节点之后,肯定平衡了,因此退出 - // 另外,翻转之后,若刚好是根节点。则赋值给tree - // 方便循环外面判断 - break; - } - else if (brother->right != NULL && RBT_IS_RED(brother->right)) - { - // 黑bother存在right节点,且right为红色。(且left不红的情况) - // 父节点颜色未知 - // case 2 - // 注意:这样写代码的话,则必须在case2前先判断case1/case3 - RBT_SET_RED(brother); - RBT_SET_BLACK(brother->right); - node_temp = rbtree_turn_left(brother); - // 随后转化为了 case 1 - } - else - { - // 黑brother的子节点为双空或双黑 - // case 4 - if(RBT_IS_BLACK(father)) - { - // 若父节点为黑,则将brother染为红色, - // 但是总体是少了一黑,因此以父节点为tree向上递归 - RBT_SET_RED(brother); - tree = father; - } - else - { - // brother双子空,则表示brother和被删除的节点平衡 - // 因此直接转换颜色即可 - RBT_SET_RED(brother); - RBT_SET_BLACK(father); - // 删除节点之后,肯定平衡了,因此退出 - break; - } - } - } + while ((tree->parent != NULL) && RBT_IS_BLACK(tree)) + { + father = get_parent_node(tree); + if (tree == father->left) + { + brother = father->right; + if (RBT_IS_RED(brother)) + { + // 根据rbtree性质,父节点必定为黑, + // 红brother的子节点双黑或者双空 + // case 5 + RBT_SET_BLACK(brother); + RBT_SET_RED(father); + node_temp = rbtree_turn_left(father); + // 节点未删除时平衡,但是删除之后又不平衡了 + // 因此需要继续判断 + } + else if(brother->right != NULL && RBT_IS_RED(brother->right)) + { + // 黑bother存在right节点,并且为红色的情况 + // 父节点颜色未知 + // case 1 (仅右子红)和 case 3(双子红) 本质上一样 + RBT_COLOR_ASSIGN(brother,father); //color(f) -> color(b) + RBT_SET_BLACK(father); + RBT_SET_BLACK(brother->right); + tree = rbtree_turn_left(father); + // 删除节点之后,肯定平衡了,因此退出 + // 另外,翻转之后,若刚好是根节点。则赋值给tree + // 方便循环外面判断 + break; + } + else if(brother->left != NULL && RBT_IS_RED(brother->left)) + { + // 黑bother仅有left节点,且left为红色,(且rigth不红的情况) + // 父节点颜色未知 + // case 2 + // 注意:这样写代码的话,则必须在case2前先判断case1/case3 + RBT_SET_RED(brother); + RBT_SET_BLACK(brother->left); + node_temp = rbtree_turn_right(brother); + // 随后转化为了case 1 + } + else + { + // 黑brother的子节点为双空或双黑 + // case 4 + if(RBT_IS_BLACK(father)) + { + // 若父节点为黑,则将brother染为红色, + // 但是总体是少了一黑,因此以父节点为tree向上递归 + RBT_SET_RED(brother); + tree = father; + } + else + { + // brother双子空,则表示brother和被删除的节点平衡 + // 因此直接转换颜色即可 + RBT_SET_RED(brother); + RBT_SET_BLACK(father); + // 删除节点之后,肯定平衡了,因此退出 + break; + } + } + } + else + { + brother = father->left; + if (RBT_IS_RED(brother)) + { + // 根据rbtree性质,父节点必定为黑, + // 红brother的子节点双黑或者双空 + // case 5 + RBT_SET_BLACK(brother); + RBT_SET_RED(father); + node_temp = rbtree_turn_right(father); + // 节点未删除时平衡,但是删除之后又不平衡了 + // 因此需要继续判断 + } + else if (brother->left != NULL && RBT_IS_RED(brother->left)) + { + // 黑bother存在left节点,并且为红色的情况 + // 父节点颜色未知 + // case 1 (仅右子红)和 case 3(双子红) 本质上一样 + RBT_COLOR_ASSIGN(brother,father); + RBT_SET_BLACK(father); + RBT_SET_BLACK(brother->left); + tree = rbtree_turn_right(father); + // 删除节点之后,肯定平衡了,因此退出 + // 另外,翻转之后,若刚好是根节点。则赋值给tree + // 方便循环外面判断 + break; + } + else if (brother->right != NULL && RBT_IS_RED(brother->right)) + { + // 黑bother存在right节点,且right为红色。(且left不红的情况) + // 父节点颜色未知 + // case 2 + // 注意:这样写代码的话,则必须在case2前先判断case1/case3 + RBT_SET_RED(brother); + RBT_SET_BLACK(brother->right); + node_temp = rbtree_turn_left(brother); + // 随后转化为了 case 1 + } + else + { + // 黑brother的子节点为双空或双黑 + // case 4 + if(RBT_IS_BLACK(father)) + { + // 若父节点为黑,则将brother染为红色, + // 但是总体是少了一黑,因此以父节点为tree向上递归 + RBT_SET_RED(brother); + tree = father; + } + else + { + // brother双子空,则表示brother和被删除的节点平衡 + // 因此直接转换颜色即可 + RBT_SET_RED(brother); + RBT_SET_BLACK(father); + // 删除节点之后,肯定平衡了,因此退出 + break; + } + } + } - // 在处理过程中,防止根节点丢失 - if (node_temp != NULL && node_temp->parent == NULL) - { - head->tree = node_temp; - } - } + // 在处理过程中,防止根节点丢失 + if (node_temp != NULL && node_temp->parent == NULL) + { + head->tree = node_temp; + } + } - if (tree->parent == NULL) - { - head->tree = tree; - } + if (tree->parent == NULL) + { + head->tree = tree; + } - RBT_SET_BLACK(head->tree); - return true; + RBT_SET_BLACK(head->tree); + return true; } bool rbtree_get_min(prbtree_t head, rbtree_data_t *data) { - prbtree_node_t root; + prbtree_node_t root; - if ((head == NULL) || head->tree == NULL) - { - return false; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return false; + } + root = head->tree; - while (root != NULL) - { - if (root->left != NULL) - { - root = root->left; - } - else - { - *data = root->data; - return true; - } - } - return false; + while (root != NULL) + { + if (root->left != NULL) + { + root = root->left; + } + else + { + *data = root->data; + return true; + } + } + return false; } bool rbtree_get_max(prbtree_t head, rbtree_data_t *data) { - prbtree_node_t root; - if ((head == NULL) || head->tree == NULL) - { - return false; - } - root = head->tree; + prbtree_node_t root; + if ((head == NULL) || head->tree == NULL) + { + return false; + } + root = head->tree; - while (root != NULL) - { - if (root->right != NULL) - { - root = root->right; - } - else - { - *data = root->data; - return true; - } - } - return false; + while (root != NULL) + { + if (root->right != NULL) + { + root = root->right; + } + else + { + *data = root->data; + return true; + } + } + return false; } #if 1 void rbtree_traversal_depth_preorder(prbtree_t head, tree_data_disp_t tree_data_disp) { - pstack_t stack; - prbtree_node_t root; - prbtree_node_t tree_node; + pstack_t stack; + prbtree_node_t root; + prbtree_node_t tree_node; - if ((head == NULL) || head->tree == NULL) - { - return; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return; + } + root = head->tree; - stack_init(&stack); - tree_node = root; - while (!stack_empty(stack) || tree_node != NULL) - { - if (tree_node != NULL) - { - tree_data_disp(tree_node->data); + stack_init(&stack); + tree_node = root; + while (!stack_empty(stack) || tree_node != NULL) + { + if (tree_node != NULL) + { + tree_data_disp(tree_node->data); - stack_push(stack, tree_node); - tree_node = tree_node->left; - } - else - { - stack_pop(stack, &tree_node); - tree_node = tree_node->right; - } - } + stack_push(stack, tree_node); + tree_node = tree_node->left; + } + else + { + stack_pop(stack, &tree_node); + tree_node = tree_node->right; + } + } - stack_destroy(&stack); + stack_destroy(&stack); } void rbtree_traversal_depth_inorder(prbtree_t head, tree_data_disp_t tree_data_disp) { - pstack_t stack; - prbtree_node_t root; - prbtree_node_t tree_node; + pstack_t stack; + prbtree_node_t root; + prbtree_node_t tree_node; - if ((head == NULL) || head->tree == NULL) - { - return; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return; + } + root = head->tree; - stack_init(&stack); - tree_node = root; - while (!stack_empty(stack) || tree_node != NULL) - { - if (tree_node != NULL) - { - stack_push(stack, tree_node); - tree_node = tree_node->left; - } - else - { - stack_pop(stack, &tree_node); - tree_data_disp(tree_node->data); - tree_node = tree_node->right; - } - } + stack_init(&stack); + tree_node = root; + while (!stack_empty(stack) || tree_node != NULL) + { + if (tree_node != NULL) + { + stack_push(stack, tree_node); + tree_node = tree_node->left; + } + else + { + stack_pop(stack, &tree_node); + tree_data_disp(tree_node->data); + tree_node = tree_node->right; + } + } - stack_destroy(&stack); + stack_destroy(&stack); } void rbtree_traversal_depth_postorder(prbtree_t head, tree_data_disp_t tree_data_disp) { - pstack_t stack; - pstack_t stack_disp; - prbtree_node_t root; - prbtree_node_t tree_node; + pstack_t stack; + pstack_t stack_disp; + prbtree_node_t root; + prbtree_node_t tree_node; - if ((head == NULL) || head->tree == NULL) - { - return; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return; + } + root = head->tree; - stack_init(&stack); - stack_init(&stack_disp); - tree_node = root; - while (!stack_empty(stack) || tree_node != NULL) - { - if (tree_node != NULL) - { - stack_push(stack_disp, tree_node); + stack_init(&stack); + stack_init(&stack_disp); + tree_node = root; + while (!stack_empty(stack) || tree_node != NULL) + { + if (tree_node != NULL) + { + stack_push(stack_disp, tree_node); - stack_push(stack, tree_node); - tree_node = tree_node->right; - } - else - { - stack_pop(stack, &tree_node); - tree_node = tree_node->left; - } - } + stack_push(stack, tree_node); + tree_node = tree_node->right; + } + else + { + stack_pop(stack, &tree_node); + tree_node = tree_node->left; + } + } - while (!stack_empty(stack_disp)) - { - stack_pop(stack_disp, &tree_node); - tree_data_disp(tree_node->data); - } + while (!stack_empty(stack_disp)) + { + stack_pop(stack_disp, &tree_node); + tree_data_disp(tree_node->data); + } - stack_destroy(&stack); - stack_destroy(&stack_disp); + stack_destroy(&stack); + stack_destroy(&stack_disp); } #else // ------------------------------------------------- @@ -836,350 +836,350 @@ void rbtree_traversal_depth_postorder(prbtree_t head, tree_data_disp_t tree_data // ------------------------------------------------- void rbtree_traversal_depth_preorder(prbtree_t head, tree_data_disp_t tree_data_disp) { - pstack_t stack; - prbtree_node_t root; - prbtree_node_t tree_node; + pstack_t stack; + prbtree_node_t root; + prbtree_node_t tree_node; - if ((head == NULL) || head->tree == NULL) - { - return; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return; + } + root = head->tree; - stack_init(&stack); - stack_push(stack, root); - tree_data_disp(root->data); - while (!stack_empty(stack)) - { - stack_get_top(stack, &tree_node); + stack_init(&stack); + stack_push(stack, root); + tree_data_disp(root->data); + while (!stack_empty(stack)) + { + stack_get_top(stack, &tree_node); - if (tree_node->left != NULL && !RBT_IS_VISITED_LEFT(tree_node)) - { - RBT_VISIT_LEFT(tree_node); + if (tree_node->left != NULL && !RBT_IS_VISITED_LEFT(tree_node)) + { + RBT_VISIT_LEFT(tree_node); - stack_push(stack, tree_node->left); - tree_node = tree_node->left; + stack_push(stack, tree_node->left); + tree_node = tree_node->left; - tree_data_disp(tree_node->data); - } - else if (tree_node->right != NULL && !RBT_IS_VISITED_RIGHT(tree_node)) - { - RBT_VISIT_RIGHT(tree_node); + tree_data_disp(tree_node->data); + } + else if (tree_node->right != NULL && !RBT_IS_VISITED_RIGHT(tree_node)) + { + RBT_VISIT_RIGHT(tree_node); - stack_push(stack, tree_node->right); - tree_node = tree_node->right; + stack_push(stack, tree_node->right); + tree_node = tree_node->right; - tree_data_disp(tree_node->data); - } - else - { - RBT_VISIT_CLR(tree_node); - stack_pop(stack, &tree_node); - } - } + tree_data_disp(tree_node->data); + } + else + { + RBT_VISIT_CLR(tree_node); + stack_pop(stack, &tree_node); + } + } - stack_destroy(&stack); + stack_destroy(&stack); } void rbtree_traversal_depth_inorder(prbtree_t head, tree_data_disp_t tree_data_disp) { - pstack_t stack; - prbtree_node_t root; - prbtree_node_t tree_node; + pstack_t stack; + prbtree_node_t root; + prbtree_node_t tree_node; - if ((head == NULL) || head->tree == NULL) - { - return; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return; + } + root = head->tree; - stack_init(&stack); - stack_push(stack, root); - while (!stack_empty(stack)) - { - stack_get_top(stack, &tree_node); + stack_init(&stack); + stack_push(stack, root); + while (!stack_empty(stack)) + { + stack_get_top(stack, &tree_node); - if (tree_node->left != NULL && !RBT_IS_VISITED_LEFT(tree_node)) - { - RBT_VISIT_LEFT(tree_node); - - stack_push(stack, tree_node->left); - tree_node = tree_node->left; - } - else if (tree_node->right != NULL && !RBT_IS_VISITED_RIGHT(tree_node)) - { - RBT_VISIT_RIGHT(tree_node); - - tree_data_disp(tree_node->data); - - stack_push(stack, tree_node->right); - tree_node = tree_node->right; - } - else - { - if (!RBT_IS_VISITED_RIGHT(tree_node)) - { - tree_data_disp(tree_node->data); - } + if (tree_node->left != NULL && !RBT_IS_VISITED_LEFT(tree_node)) + { + RBT_VISIT_LEFT(tree_node); + + stack_push(stack, tree_node->left); + tree_node = tree_node->left; + } + else if (tree_node->right != NULL && !RBT_IS_VISITED_RIGHT(tree_node)) + { + RBT_VISIT_RIGHT(tree_node); + + tree_data_disp(tree_node->data); + + stack_push(stack, tree_node->right); + tree_node = tree_node->right; + } + else + { + if (!RBT_IS_VISITED_RIGHT(tree_node)) + { + tree_data_disp(tree_node->data); + } - RBT_VISIT_CLR(tree_node); - stack_pop(stack, &tree_node); - } - } + RBT_VISIT_CLR(tree_node); + stack_pop(stack, &tree_node); + } + } - stack_destroy(&stack); + stack_destroy(&stack); } void rbtree_traversal_depth_postorder(prbtree_t head, tree_data_disp_t tree_data_disp) { - pstack_t stack; - prbtree_node_t root; - prbtree_node_t tree_node; + pstack_t stack; + prbtree_node_t root; + prbtree_node_t tree_node; - if ((head == NULL) || head->tree == NULL) - { - return; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return; + } + root = head->tree; - stack_init(&stack); - stack_push(stack, root); - while (!stack_empty(stack)) - { - stack_get_top(stack, &tree_node); + stack_init(&stack); + stack_push(stack, root); + while (!stack_empty(stack)) + { + stack_get_top(stack, &tree_node); - if (tree_node->left != NULL && !RBT_IS_VISITED_LEFT(tree_node)) - { - RBT_VISIT_LEFT(tree_node); + if (tree_node->left != NULL && !RBT_IS_VISITED_LEFT(tree_node)) + { + RBT_VISIT_LEFT(tree_node); - stack_push(stack, tree_node->left); - tree_node = tree_node->left; - } - else if (tree_node->right != NULL && !RBT_IS_VISITED_RIGHT(tree_node)) - { - RBT_VISIT_RIGHT(tree_node); + stack_push(stack, tree_node->left); + tree_node = tree_node->left; + } + else if (tree_node->right != NULL && !RBT_IS_VISITED_RIGHT(tree_node)) + { + RBT_VISIT_RIGHT(tree_node); - stack_push(stack, tree_node->right); - tree_node = tree_node->right; - } - else - { - RBT_VISIT_CLR(tree_node); - stack_pop(stack, &tree_node); + stack_push(stack, tree_node->right); + tree_node = tree_node->right; + } + else + { + RBT_VISIT_CLR(tree_node); + stack_pop(stack, &tree_node); - tree_data_disp(tree_node->data); - } - } + tree_data_disp(tree_node->data); + } + } - stack_destroy(&stack); + stack_destroy(&stack); } #endif void rbtree_traversal_breadth(prbtree_t head, tree_data_disp_t tree_data_disp) { - pqueue_t queue; - prbtree_node_t root; - prbtree_node_t tree_node; + pqueue_t queue; + prbtree_node_t root; + prbtree_node_t tree_node; - if ((head == NULL) || head->tree == NULL) - { - return; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + return; + } + root = head->tree; - queue_init(&queue); - queue_in(queue, root); - if (root != NULL) - { - while (!queue_empty(queue)) - { - queue_out(queue, &tree_node); - if (tree_node->left != NULL) - { - queue_in(queue, tree_node->left); - } - if (tree_node->right != NULL) - { - queue_in(queue, tree_node->right); - } + queue_init(&queue); + queue_in(queue, root); + if (root != NULL) + { + while (!queue_empty(queue)) + { + queue_out(queue, &tree_node); + if (tree_node->left != NULL) + { + queue_in(queue, tree_node->left); + } + if (tree_node->right != NULL) + { + queue_in(queue, tree_node->right); + } - tree_data_disp(tree_node->data); - } - } + tree_data_disp(tree_node->data); + } + } - queue_destroy(&queue); + queue_destroy(&queue); } static bool rbtree_node_check(prbtree_node_t tree_node) { - // check - if (tree_node->parent == NULL) - { - if (RBT_IS_RED(tree_node)) - { - return false; - } - } - else - { - if (RBT_IS_RED(tree_node)) - { - if (tree_node->left != NULL && tree_node->right != NULL) - { - if (RBT_IS_RED(tree_node->left) || RBT_IS_RED(tree_node->right)) - { - // error - return false; - } - } - else if (tree_node->left != NULL && tree_node->right == NULL) - { - // error - return false; - } - else if (tree_node->left == NULL && tree_node->right != NULL) - { - // error - return false; - } - else - { - // pass - } - } - else - { - if (tree_node->left != NULL && tree_node->right == NULL) - { - if (RBT_IS_BLACK(tree_node->left)) - { - // error - return false; - } - } - else if (tree_node->left == NULL && tree_node->right != NULL) - { - if (RBT_IS_BLACK(tree_node->right)) - { - // error - return false; - } - } - else - { - // pass - } - } - } + // check + if (tree_node->parent == NULL) + { + if (RBT_IS_RED(tree_node)) + { + return false; + } + } + else + { + if (RBT_IS_RED(tree_node)) + { + if (tree_node->left != NULL && tree_node->right != NULL) + { + if (RBT_IS_RED(tree_node->left) || RBT_IS_RED(tree_node->right)) + { + // error + return false; + } + } + else if (tree_node->left != NULL && tree_node->right == NULL) + { + // error + return false; + } + else if (tree_node->left == NULL && tree_node->right != NULL) + { + // error + return false; + } + else + { + // pass + } + } + else + { + if (tree_node->left != NULL && tree_node->right == NULL) + { + if (RBT_IS_BLACK(tree_node->left)) + { + // error + return false; + } + } + else if (tree_node->left == NULL && tree_node->right != NULL) + { + if (RBT_IS_BLACK(tree_node->right)) + { + // error + return false; + } + } + else + { + // pass + } + } + } - return true; + return true; } bool rbtree_check(prbtree_t head) { - pstack_t stack; - prbtree_node_t root; - prbtree_node_t tree_node; + pstack_t stack; + prbtree_node_t root; + prbtree_node_t tree_node; - bool ret = true; - uint32_t black_cnt = 0, black_cnt_max = 0; + bool ret = true; + uint32_t black_cnt = 0, black_cnt_max = 0; - if ((head == NULL) || head->tree == NULL) - { - // ok - return ret; - } - root = head->tree; + if ((head == NULL) || head->tree == NULL) + { + // ok + return ret; + } + root = head->tree; - if (RBT_IS_RED(root)) - { - ret = false; - return ret; - } - else - { - black_cnt++; - if (black_cnt > black_cnt_max) - { - black_cnt_max = black_cnt; - } - } + if (RBT_IS_RED(root)) + { + ret = false; + return ret; + } + else + { + black_cnt++; + if (black_cnt > black_cnt_max) + { + black_cnt_max = black_cnt; + } + } - stack_init(&stack); - stack_push(stack, root); - while (!stack_empty(stack)) - { - stack_get_top(stack,&tree_node); + stack_init(&stack); + stack_push(stack, root); + while (!stack_empty(stack)) + { + stack_get_top(stack,&tree_node); - if (tree_node->left != NULL && !RBT_IS_VISITED_LEFT(tree_node)) - { - RBT_VISIT_LEFT(tree_node); + if (tree_node->left != NULL && !RBT_IS_VISITED_LEFT(tree_node)) + { + RBT_VISIT_LEFT(tree_node); - stack_push(stack, tree_node->left); - tree_node = tree_node->left; + stack_push(stack, tree_node->left); + tree_node = tree_node->left; - if (RBT_IS_BLACK(tree_node)) - { - black_cnt++; - if (black_cnt > black_cnt_max) - { - black_cnt_max = black_cnt; - } - } - } - else if (tree_node->right != NULL && !RBT_IS_VISITED_RIGHT(tree_node)) - { - RBT_VISIT_RIGHT(tree_node); + if (RBT_IS_BLACK(tree_node)) + { + black_cnt++; + if (black_cnt > black_cnt_max) + { + black_cnt_max = black_cnt; + } + } + } + else if (tree_node->right != NULL && !RBT_IS_VISITED_RIGHT(tree_node)) + { + RBT_VISIT_RIGHT(tree_node); - stack_push(stack, tree_node->right); - tree_node = tree_node->right; + stack_push(stack, tree_node->right); + tree_node = tree_node->right; - if (RBT_IS_BLACK(tree_node)) - { - black_cnt++; - if (black_cnt > black_cnt_max) - { - black_cnt_max = black_cnt; - } - } - } - else - { - if (tree_node->left == NULL && tree_node->right == NULL) - { - if (black_cnt != black_cnt_max) - { - ret = false; - goto black_check_exit; - } - } + if (RBT_IS_BLACK(tree_node)) + { + black_cnt++; + if (black_cnt > black_cnt_max) + { + black_cnt_max = black_cnt; + } + } + } + else + { + if (tree_node->left == NULL && tree_node->right == NULL) + { + if (black_cnt != black_cnt_max) + { + ret = false; + goto black_check_exit; + } + } - RBT_VISIT_CLR(tree_node); - stack_pop(stack, &tree_node); + RBT_VISIT_CLR(tree_node); + stack_pop(stack, &tree_node); - if (RBT_IS_BLACK(tree_node)) - { - if (black_cnt > 0) - { - black_cnt--; - } - } + if (RBT_IS_BLACK(tree_node)) + { + if (black_cnt > 0) + { + black_cnt--; + } + } - // check node - if (true != rbtree_node_check(tree_node)) - { - ret = false; - goto black_check_exit; - } - } - } + // check node + if (true != rbtree_node_check(tree_node)) + { + ret = false; + goto black_check_exit; + } + } + } black_check_exit: - stack_destroy(&stack); - return ret; + stack_destroy(&stack); + return ret; } #endif // RBTREE == 1 diff --git a/src/stack.c b/src/stack.c index 64a87bd..1f58b21 100644 --- a/src/stack.c +++ b/src/stack.c @@ -1,4 +1,13 @@ - +/** + * @file stack.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #include "stack.h" static uint32_t stack_capacity(struct _stack* self) diff --git a/src/tree.c b/src/tree.c index 95f68ab..1f75ad8 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1,4 +1,13 @@ - +/** + * @file tree.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #include "tree.h" #if RAVLTREE == 1 @@ -1393,7 +1402,7 @@ static bool tree_rebalance(ptree_t head, ptree_node_t tree) #endif -static tree_node_t * tree_node_new(struct _tree* self, void* obj) +static tree_node_t tree_node_new(struct _tree* self, void* obj) { void * obj_new = malloc(self->_obj_size); if (obj_new == NULL) @@ -1402,7 +1411,7 @@ static tree_node_t * tree_node_new(struct _tree* self, void* obj) } memmove(obj_new, obj, self->_obj_size); - struct _tree_node* node_new = (struct _queue_node*)malloc(sizeof(struct _tree_node)); + struct _tree_node* node_new = (struct _tree_node*)malloc(sizeof(struct _tree_node)); if(node_new == NULL) { goto done; diff --git a/src/unicstl.c b/src/unicstl.c index ec5c781..a7f0671 100644 --- a/src/unicstl.c +++ b/src/unicstl.c @@ -1,2 +1,11 @@ - +/** + * @file unicstl.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #include "unicstl.h" diff --git a/test/test.c b/test/test.c index 931997d..4699460 100644 --- a/test/test.c +++ b/test/test.c @@ -27,10 +27,10 @@ int main() printf("----- unicstl test -----\n"); // while (1) { - list_test(); + test_list(); test_stack(); - deque_test(); - queue_test(); + test_deque(); + test_queue(); // tree_test(); // rbtree_test(); diff --git a/test/test.h b/test/test.h index e9e12c6..c5c079d 100644 --- a/test/test.h +++ b/test/test.h @@ -26,11 +26,11 @@ void print_str(void* obj); * @brief test function * */ -void list_test(void); +void test_list(void); void test_stack(void); -void deque_test(void); +void test_deque(void); -void queue_test(void); +void test_queue(void); void tree_test(void); void rbtree_test(void); diff --git a/test/test_deque.c b/test/test_deque.c index 324d11b..6150f2c 100644 --- a/test/test_deque.c +++ b/test/test_deque.c @@ -1,7 +1,16 @@ - +/** + * @file test_deque.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-06-23 + * + * @copyright Copyright (c) 2024 + * + */ #include "test.h" -static void deque_test_num(void) +static void test_deque_num(void) { uint32_t i = 0; int data[] = { 1,2,3,4,5,6,7,8,9,10 }; @@ -12,7 +21,7 @@ static void deque_test_num(void) deque_init(&dq, sizeof(int)); dq.print_obj = print_num; - printf("\n\n----- deque_test_num -----\n"); + printf("\n\n----- test_deque_num -----\n"); printf("----- after push_back -----\n"); for (i = 0; i < len; i++) @@ -169,7 +178,7 @@ static void deque_test_num(void) dq.destory(&dq); } -static void deque_test_struct(void) +static void test_deque_struct(void) { uint32_t i = 0; struct _student data[] = { @@ -184,7 +193,7 @@ static void deque_test_struct(void) deque_init(&dq, sizeof(struct _student)); dq.print_obj = print_struct; - printf("\n\n----- deque_test_struct -----\n"); + printf("\n\n----- test_deque_struct -----\n"); printf("----- after push_back -----\n"); for (i = 0; i < len; i++) @@ -343,8 +352,8 @@ static void deque_test_struct(void) dq.destory(&dq); } -void deque_test(void) +void test_deque(void) { - deque_test_num(); - deque_test_struct(); + test_deque_num(); + test_deque_struct(); } diff --git a/test/test_list.c b/test/test_list.c index 2f2ee90..aa0d43a 100644 --- a/test/test_list.c +++ b/test/test_list.c @@ -291,7 +291,7 @@ static void test_list_struct(void) list.destory(&list); } -void list_test(void) +void test_list(void) { test_list_num(); test_list_struct(); diff --git a/test/test_queue.c b/test/test_queue.c index ab10927..e11133b 100644 --- a/test/test_queue.c +++ b/test/test_queue.c @@ -1,154 +1,7 @@ #include "test.h" -#if QUEUE_TEST == 1 - -void queue_test(void) -{ - int32_t i = 0; - uint32_t size; - queue_data_t dat[10] = {0,1,2,3,4,5,6,7,8,9}; - queue_data_t tmp; - pqueue_t que; - - if(!queue_init(&que)) - { - printf("failure -> queue_init\n"); - } - printf("success -> queue_init\n"); - - for(i = 0; i < 10; i++) - { - if(!queue_in(que,dat[i])) - { - printf("failure -> queue_in\n"); - } - if(!queue_get_front(que,&tmp)) - { - printf("failure -> queue_get_front\t"); - } - else - { - printf(" front = %d",tmp); - } - - if(!queue_get_rear(que,&tmp)) - { - printf("failure -> queue_get_rear\n"); - } - else - { - printf(" rear = %d\n",tmp); - } - } - printf("success -> queue_in\n"); - if(!queue_empty(que)) - { - printf("success -> queue is not empty!\n"); - } - else - { - printf("failure -> queue is not empty!\n"); - } - - size = queue_get_size(que); - if (size != 10) - { - printf("failure -> the size of queue is : %d\n", size); - } - else - { - printf("success -> the size of queue is : %d\n", size); - } - - printf("success -> queue_empty\n"); - for(i = 0; i < 10; i++) - { - if(!queue_get_front(que,&tmp)) - { - printf("failure -> queue_get_front\t"); - } - else - { - printf(" front = %d\t",tmp); - } - if(!queue_get_rear(que,&tmp)) - { - printf("failure -> queue_get_rear\n"); - } - else - { - printf(" rear = %d\n",tmp); - } - queue_out(que,&tmp); - } - printf("success -> queue_out\n"); - if(queue_empty(que)) - { - printf("success -> queue is empty!\n"); - } - - size = queue_get_size(que); - if (size != 0) - { - printf("failure -> the size of queue is : %d\n", size); - } - else - { - printf("success -> the size of queue is : %d\n", size); - } - - for(i = 0; i < 5; i++) - { - if(!queue_in(que,dat[i])) - { - printf("failure -> queue_in\n"); - } - } - - if(!queue_empty(que)) - { - printf("success -> queue is not empty!\n"); - queue_clear(que); - printf("success -> queue_clear\n"); - - if(queue_empty(que)) - { - printf("success -> queue is empty!\n"); - } - else - { - printf("failure -> queue is not empty!\n"); - } - } - - queue_destroy(&que); - printf("success -> queue_destroy\n"); - - if(!queue_in(que,dat[0])) - { - printf("success -> If que if NULL, queue_in return failure\n"); - } - - queue_out(que,&tmp); - printf("success -> queue_out invalid!\n"); - - if(queue_empty(que)) - { - printf("success -> If que is NULL, queue_empty alse return true!\n"); - } - else - { - printf("failure -> Que is NULL, but queue_empty return true!\n"); - } - - printf("----------------------------------------\n"); -} - -#else - - -static void queue_test_num(void) +static void test_queue_num(void) { uint32_t i = 0; int data[] = { 1,2,3,4,5,6,7,8,9,10 }; @@ -159,7 +12,7 @@ static void queue_test_num(void) queue_init(&queue, sizeof(int)); queue.print_obj = print_num; - printf("\n\n----- queue_test_num -----\n"); + printf("\n\n----- test_queue_num -----\n"); printf("----- after push-----\n"); for (i = 0; i < len; i++) @@ -233,7 +86,7 @@ static void queue_test_num(void) } -static void queue_test_char(void) +static void test_queue_char(void) { uint32_t i = 0; char data[] = "abcdefghijk"; @@ -245,7 +98,7 @@ static void queue_test_char(void) queue_init2(&queue, sizeof(char), 10); queue.print_obj = print_char; - printf("\n\n----- queue_test_char -----\n"); + printf("\n\n----- test_queue_char -----\n"); printf("----- after push-----\n"); for (i = 0; i < len; i++) @@ -328,11 +181,8 @@ static void queue_test_char(void) queue.destory(&queue); } -void queue_test(void) +void test_queue(void) { - // queue_test_num(); - queue_test_char(); + test_queue_num(); + test_queue_char(); } - -#endif -