From c3bd9f2e775bbfcb0a0af490fe7ae531588a8d18 Mon Sep 17 00:00:00 2001 From: kkk <18436010132@163.com> Date: Wed, 26 Jul 2023 16:50:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E4=BA=8E=E6=9C=80=E6=96=B0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BB=93=E5=BA=93=EF=BC=8C=E6=B7=BB=E5=8A=A0=E7=BA=A2?= =?UTF-8?q?=E9=BB=91=E6=A0=91=E7=9B=B8=E5=85=B3=E6=96=87=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=E6=94=B9=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APP_Framework/Applications/app_test/Kconfig | 4 + APP_Framework/Applications/app_test/Makefile | 4 + .../app_test/test_rbtree/Makefile | 12 + .../app_test/test_rbtree/README.md | 0 .../app_test/test_rbtree/rbtree.c | 397 ++++++++++++++++++ .../app_test/test_rbtree/rbtree.h | 65 +++ .../app_test/test_rbtree/test_rbtree.c | 47 +++ 7 files changed, 529 insertions(+) create mode 100755 APP_Framework/Applications/app_test/test_rbtree/Makefile create mode 100644 APP_Framework/Applications/app_test/test_rbtree/README.md create mode 100644 APP_Framework/Applications/app_test/test_rbtree/rbtree.c create mode 100644 APP_Framework/Applications/app_test/test_rbtree/rbtree.h create mode 100644 APP_Framework/Applications/app_test/test_rbtree/test_rbtree.c diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 3a103a6b3..4178db697 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -240,5 +240,9 @@ menu "test app" bool "Config test soft timer" default n + menuconfig USER_TEST_RBTREE + bool "Config test rbtree" + default n + endif endmenu diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 200e9e02a..a796cdad8 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -101,5 +101,9 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y) SRC_FILES += test_timer.c endif + ifeq ($(CONFIG_USER_TEST_RBTREE),y) + SRC_DIR += test_rbtree + endif + include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Applications/app_test/test_rbtree/Makefile b/APP_Framework/Applications/app_test/test_rbtree/Makefile new file mode 100755 index 000000000..a465fbdd1 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rbtree/Makefile @@ -0,0 +1,12 @@ +ifeq ($(CONFIG_ADD_XIZI_FEATURES),y) + SRC_FILES := rbtree.c test_rbtree.c + include $(KERNEL_ROOT)/compiler.mk +endif + +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FEATURES),y) + include $(APPDIR)/Make.defs + CSRCS += rbtree.c test_rbtree.c + include $(APPDIR)/Application.mk +endif + diff --git a/APP_Framework/Applications/app_test/test_rbtree/README.md b/APP_Framework/Applications/app_test/test_rbtree/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/APP_Framework/Applications/app_test/test_rbtree/rbtree.c b/APP_Framework/Applications/app_test/test_rbtree/rbtree.c new file mode 100644 index 000000000..8d4b7e665 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rbtree/rbtree.c @@ -0,0 +1,397 @@ +#include "rbtree.h" +#include +#include + +struct Queue* front = NULL; +struct Queue* rear = NULL; + +struct Node* pfront() +{ + struct Node* data ; + data = front->data; + return data; +} + +int isempty() +{ + if(front==NULL) + return 1; + + else + return 0; +} + +void dequeue() +{ + if(isempty()) + return ; + + struct Queue* temp = front; + front = front->next; + free(temp); +} + + +void enqueue(struct Node* data) +{ + struct Queue* temp =(struct Queue*)malloc(sizeof(struct Queue)); + temp->data = data; + temp->next = NULL; + + if(front==NULL && rear == NULL) + { + front = rear = temp; + return; + } + + rear->next = temp; + rear = temp; +} + +void levelorder(struct Node* root) +{ + if(root==NULL) + return; + + enqueue(root); + + while(!isempty()) + { + struct Node* current = pfront(); + printf("%d ",current->data); + + if(current->left!=NULL) + enqueue(current->left); + + if(current->right!=NULL) + enqueue(current->right); + + dequeue(); + } +} + +void LeftRotate(struct Node** T,struct Node** x) +{ + struct Node* y = (*x)->right; + (*x)->right = y->left; + + if(y->left!=NULL) + y->left->parent = *x; + + y->parent = (*x)->parent; + + if((*x)->parent == NULL) + *T = y; + + else if(*x == (*x)->parent->left) + (*x)->parent->left = y; + + else + (*x)->parent->right = y; + + y->left = *x; + + (*x)->parent = y; + +} +void RightRotate(struct Node** T,struct Node** x) +{ + struct Node* y = (*x)->left; + (*x)->left = y->right; + + if(y->right!=NULL) + y->right->parent = *x; + + y->parent = (*x)->parent; + + if((*x)->parent==NULL) + *T = y; + + else if((*x)== (*x)->parent->left) + (*x)->parent->left = y; + + else + (*x)->parent->right = y; + + y->right = *x; + (*x)->parent = y; + +} + +void RB_insert_fixup(struct Node** T, struct Node** z) +{ + struct Node* grandparent = NULL; + struct Node* parentpt = NULL; + + while(((*z)!=*T)&& ((*z)->color!= BLACK) && ((*z)->parent->color == RED)) + { + parentpt = (*z)->parent; + grandparent = (*z)->parent->parent; + + if(parentpt == grandparent->left) + { + struct Node* uncle = grandparent->right; + + if(uncle!=NULL && uncle->color == RED) + { + grandparent->color = RED; + parentpt->color = BLACK; + uncle->color = BLACK; + *z = grandparent; + } + + else + { + if((*z) == parentpt->right) + { + LeftRotate(T,&parentpt); + (*z) = parentpt; + parentpt = (*z)->parent; + } + + RightRotate(T,&grandparent); + parentpt->color = BLACK; + grandparent->color = RED; + (*z) = parentpt; + } + } + + else + { + struct Node* uncle = grandparent->left; + + if(uncle!=NULL && uncle->color == RED) + { + grandparent->color = RED; + parentpt->color = BLACK; + uncle->color = BLACK; + (*z) = grandparent; + } + + else + { + if((*z) == parentpt->left) + { + RightRotate(T,&parentpt); + (*z) = parentpt; + parentpt = (*z)->parent; + } + + LeftRotate(T,&grandparent); + parentpt->color = BLACK; + grandparent->color = RED; + (*z) = parentpt; + } + } + } + (*T)->color = BLACK; + +} + +struct Node* RB_insert(struct Node* T,int data) +{ + struct Node* z = (struct Node*)malloc(sizeof(struct Node)); + z->data = data; + z->left = NULL; + z->right = NULL; + z->parent = NULL; + z->color = RED; + + struct Node* y = NULL; + struct Node* x = T;//root + + while(x!=NULL) + { + y = x; + if(z->data < x->data) + x = x->left; + + else + x = x->right; + } + z->parent = y; + + if(y==NULL) + T = z; + + else if(z->data < y->data) + y->left = z; + + else + y->right = z; + + RB_insert_fixup(&T,&z); + + return T; +} + +void preorder(struct Node* root) +{ + if(root==NULL) + return; + + printf("%d ",root->data); + preorder(root->left); + preorder(root->right); +} + +struct Node* Tree_minimum(struct Node* node) +{ + while(node->left!=NULL) + node = node->left; + + return node; +} + +void RB_delete_fixup(struct Node** T, struct Node** x) +{ + while((*x)!=*T && (*x)->color == BLACK) + { + if((*x)==(*x)->parent->left) + { + struct Node* w = (*x)->parent->right; + + if(w->color==RED) + { + w->color = BLACK; + (*x)->parent->color = BLACK; + LeftRotate(T,&((*x)->parent)); + w = (*x)->parent->right; + } + + if(w->left->color==BLACK && w->right->color == BLACK) + { + w->color = RED; + (*x) = (*x)->parent; + } + + else + { + if(w->right->color == BLACK) + { + w->left->color = BLACK; + w->color = RED; + RightRotate(T,&w); + w = (*x)->parent->right; + } + + w->color = (*x)->parent->color; + (*x)->parent->color = BLACK; + w->right->color = BLACK; + LeftRotate(T,&((*x)->parent)); + (*x) = *T; + } + } + + else + { + struct Node* w = (*x)->parent->left; + + if(w->color==RED) + { + w->color = BLACK; + (*x)->parent->color = BLACK; + RightRotate(T,&((*x)->parent)); + w = (*x)->parent->left; + } + + if(w->right->color==BLACK && w->left->color == BLACK) + { + w->color = RED; + (*x) = (*x)->parent; + } + + else + { + if(w->left->color == BLACK) + { + w->right->color = BLACK; + w->color = RED; + LeftRotate(T,&w); + w = (*x)->parent->left; + } + + w->color = (*x)->parent->color; + (*x)->parent->color = BLACK; + w->left->color = BLACK; + RightRotate(T,&((*x)->parent)); + (*x) = *T; + } + } + } + (*x)->color = BLACK; + +} + +void RB_transplat(struct Node** T, struct Node** u,struct Node** v) +{ + if((*u)->parent == NULL) + *T = *v; + + else if((*u)==(*u)->parent->left) + (*u)->parent->left = *v; + else + (*u)->parent->right = *v; + + if((*v)!=NULL) + (*v)->parent = (*u)->parent; +} + +struct Node* RB_delete(struct Node *T,struct Node* z) +{ + struct Node *y = z; + enum type yoc; + yoc = z->color; // y's original color + + struct Node* x; + + if(z->left==NULL ) + { + x = z->right; + RB_transplat(&T,&z,&(z->right)); + } + + else if(z->right==NULL ) + { + x = z->left; + RB_transplat(&T,&z,&(z->left)); + } + + else + { + y = Tree_minimum(z->right); + yoc = y->color; + x = y->right; + + if(y->parent==z) + x->parent = y; + + else + { + RB_transplat(&T,&y,&(y->right)); + y->right = z->right; + y->right->parent = y; + } + + RB_transplat(&T,&z,&y); + y->left = z->left; + y->left->parent = y; + y->color = z->color; + } + + if(yoc==BLACK) + RB_delete_fixup(&T,&x); + + return T; +} + +struct Node* BST_search(struct Node* root, int x) +{ + if(root==NULL || root->data == x) + return root; + + if(root->data > x) + return BST_search(root->left,x); + else + return BST_search(root->right,x); +} \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_rbtree/rbtree.h b/APP_Framework/Applications/app_test/test_rbtree/rbtree.h new file mode 100644 index 000000000..68137bb82 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rbtree/rbtree.h @@ -0,0 +1,65 @@ +#ifndef __LIST_H__ +#define __LIST_H__ + +#include +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + + +enum type {RED,BLACK}; + +struct Node +{ + int data; + struct Node* left; + struct Node* right; + struct Node* parent; + enum type color; +}; + +struct Queue +{ + struct Node* data; + struct Queue* next; +}; + + + +struct Node *pfront(); +int isempty(); + +void dequeue(); + +void enqueue(struct Node *data); + +void levelorder(struct Node *root); + +void LeftRotate(struct Node **T, struct Node **x); + +void RightRotate(struct Node **T, struct Node **x); + +void RB_insert_fixup(struct Node **T, struct Node **z); + +struct Node *RB_insert(struct Node *T, int data); + +void preorder(struct Node *root); + +struct Node *Tree_minimum(struct Node *node); + +void RB_delete_fixup(struct Node **T, struct Node **x); + +void RB_transplat(struct Node **T, struct Node **u, struct Node **v); + +struct Node *RB_delete(struct Node *T, struct Node *z); + +struct Node *BST_search(struct Node *root, int x); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.c b/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.c new file mode 100644 index 000000000..13ddd6950 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rbtree/test_rbtree.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include "rbtree.h" + + + +extern struct Queue* front; +extern struct Queue* rear; + +void Test_Rbtree(void) +{ + struct Node* RBT = NULL; + + RBT = RB_insert(RBT,2); + RBT = RB_insert(RBT,1); + RBT = RB_insert(RBT,4); + RBT = RB_insert(RBT,5); + RBT = RB_insert(RBT,9); + RBT = RB_insert(RBT,3); + RBT = RB_insert(RBT,6); + RBT = RB_insert(RBT,7); + + printf("\nPreorder - "); + preorder(RBT); + + printf("\nLevel order - "); + levelorder(RBT); + + struct Node* x = BST_search(RBT,5); + + RBT = RB_delete(RBT,x); + + printf("\nAfter deleting 5"); + + printf("\nPreorder - "); + preorder(RBT); + + front = NULL; rear = NULL; // Delete old Queue + + printf("\nLevel order - "); + levelorder(RBT); + + return ; +} + +PRIV_SHELL_CMD_FUNCTION(Test_Rbtree, a red black sample , PRIV_SHELL_CMD_MAIN_ATTR);