基于最新代码仓库,添加红黑树相关文件,并修改适配
This commit is contained in:
parent
d8021b55f8
commit
c3bd9f2e77
|
@ -240,5 +240,9 @@ menu "test app"
|
||||||
bool "Config test soft timer"
|
bool "Config test soft timer"
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
menuconfig USER_TEST_RBTREE
|
||||||
|
bool "Config test rbtree"
|
||||||
|
default n
|
||||||
|
|
||||||
endif
|
endif
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -101,5 +101,9 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y)
|
||||||
SRC_FILES += test_timer.c
|
SRC_FILES += test_timer.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_USER_TEST_RBTREE),y)
|
||||||
|
SRC_DIR += test_rbtree
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,397 @@
|
||||||
|
#include "rbtree.h"
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
#ifndef __LIST_H__
|
||||||
|
#define __LIST_H__
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include<stddef.h>
|
||||||
|
#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
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <transform.h>
|
||||||
|
#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);
|
Loading…
Reference in New Issue