add
This commit is contained in:
parent
1a6ee0234b
commit
2b1325b00d
|
@ -0,0 +1,623 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "rbtree.h"
|
||||||
|
|
||||||
|
#define rb_parent(r) ((r)->parent)
|
||||||
|
#define rb_color(r) ((r)->color)
|
||||||
|
#define rb_is_red(r) ((r)->color==RED)
|
||||||
|
#define rb_is_black(r) ((r)->color==BLACK)
|
||||||
|
#define rb_set_black(r) do { (r)->color = BLACK; } while (0)
|
||||||
|
#define rb_set_red(r) do { (r)->color = RED; } while (0)
|
||||||
|
#define rb_set_parent(r,p) do { (r)->parent = (p); } while (0)
|
||||||
|
#define rb_set_color(r,c) do { (r)->color = (c); } while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 创建红黑树
|
||||||
|
*/
|
||||||
|
RBRoot* create_rbtree()
|
||||||
|
{
|
||||||
|
RBRoot *root = (RBRoot *)malloc(sizeof(RBRoot));
|
||||||
|
root->node = NULL;
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 前序遍历
|
||||||
|
*/
|
||||||
|
static void preorder(RBTree tree)
|
||||||
|
{
|
||||||
|
if(tree != NULL)
|
||||||
|
{
|
||||||
|
printf("%d ", tree->key);
|
||||||
|
preorder(tree->left);
|
||||||
|
preorder(tree->right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void preorder_rbtree(RBRoot *root)
|
||||||
|
{
|
||||||
|
if (root)
|
||||||
|
preorder(root->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 中序遍历
|
||||||
|
*/
|
||||||
|
static void inorder(RBTree tree)
|
||||||
|
{
|
||||||
|
if(tree != NULL)
|
||||||
|
{
|
||||||
|
inorder(tree->left);
|
||||||
|
printf("%d ", tree->key);
|
||||||
|
inorder(tree->right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void inorder_rbtree(RBRoot *root)
|
||||||
|
{
|
||||||
|
if (root)
|
||||||
|
inorder(root->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 后序遍历
|
||||||
|
*/
|
||||||
|
static void postorder(RBTree tree)
|
||||||
|
{
|
||||||
|
if(tree != NULL)
|
||||||
|
{
|
||||||
|
postorder(tree->left);
|
||||||
|
postorder(tree->right);
|
||||||
|
printf("%d ", tree->key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void postorder_rbtree(RBRoot *root)
|
||||||
|
{
|
||||||
|
if (root)
|
||||||
|
postorder(root->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 递归查找键值为key的节点
|
||||||
|
*/
|
||||||
|
static Node* search(RBTree x, Type key)
|
||||||
|
{
|
||||||
|
if (x==NULL || x->key==key)
|
||||||
|
return x;
|
||||||
|
|
||||||
|
if (key < x->key)
|
||||||
|
return search(x->left, key);
|
||||||
|
else
|
||||||
|
return search(x->right, key);
|
||||||
|
}
|
||||||
|
int rbtree_search(RBRoot *root, Type key)
|
||||||
|
{
|
||||||
|
if (root)
|
||||||
|
return search(root->node, key)? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 非递归查找键值为key的节点
|
||||||
|
*/
|
||||||
|
static Node* iterative_search(RBTree x, Type key)
|
||||||
|
{
|
||||||
|
while ((x!=NULL) && (x->key!=key))
|
||||||
|
{
|
||||||
|
if (key < x->key)
|
||||||
|
x = x->left;
|
||||||
|
else
|
||||||
|
x = x->right;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
int iterative_rbtree_search(RBRoot *root, Type key)
|
||||||
|
{
|
||||||
|
if (root)
|
||||||
|
return iterative_search(root->node, key) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 返回tree为根结点的红黑树的最小结点。
|
||||||
|
*/
|
||||||
|
static Node* minimum(RBTree tree)
|
||||||
|
{
|
||||||
|
if (tree == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while(tree->left != NULL)
|
||||||
|
tree = tree->left;
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rbtree_minimum(RBRoot *root, int *val)
|
||||||
|
{
|
||||||
|
Node *node;
|
||||||
|
|
||||||
|
if (root)
|
||||||
|
node = minimum(root->node);
|
||||||
|
|
||||||
|
if (node == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*val = node->key;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 返回tree为根结点的红黑树的最大结点。
|
||||||
|
*/
|
||||||
|
static Node* maximum(RBTree tree)
|
||||||
|
{
|
||||||
|
if (tree == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while(tree->right != NULL)
|
||||||
|
tree = tree->right;
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rbtree_maximum(RBRoot *root, int *val)
|
||||||
|
{
|
||||||
|
Node *node;
|
||||||
|
|
||||||
|
if (root)
|
||||||
|
node = maximum(root->node);
|
||||||
|
|
||||||
|
if (node == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*val = node->key;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 找结点(x)的后继结点
|
||||||
|
*/
|
||||||
|
static Node* rbtree_successor(RBTree x)
|
||||||
|
{
|
||||||
|
if (x->right != NULL)
|
||||||
|
return minimum(x->right);
|
||||||
|
Node* y = x->parent;
|
||||||
|
while ((y!=NULL) && (x==y->right))
|
||||||
|
{
|
||||||
|
x = y;
|
||||||
|
y = y->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 找结点(x)的前驱结点
|
||||||
|
*/
|
||||||
|
static Node* rbtree_predecessor(RBTree x)
|
||||||
|
{
|
||||||
|
if (x->left != NULL)
|
||||||
|
return maximum(x->left);
|
||||||
|
Node* y = x->parent;
|
||||||
|
while ((y!=NULL) && (x==y->left))
|
||||||
|
{
|
||||||
|
x = y;
|
||||||
|
y = y->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 对红黑树的节点(x)进行左旋转
|
||||||
|
*/
|
||||||
|
static void rbtree_left_rotate(RBRoot *root, Node *x)
|
||||||
|
{
|
||||||
|
Node *y = x->right;
|
||||||
|
x->right = y->left;
|
||||||
|
if (y->left != NULL)
|
||||||
|
y->left->parent = x;
|
||||||
|
y->parent = x->parent;
|
||||||
|
|
||||||
|
if (x->parent == NULL)
|
||||||
|
{
|
||||||
|
root->node = y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x->parent->left == x)
|
||||||
|
x->parent->left = y;
|
||||||
|
else
|
||||||
|
x->parent->right = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
y->left = x;
|
||||||
|
x->parent = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 对红黑树的节点(y)进行右旋转
|
||||||
|
*/
|
||||||
|
static void rbtree_right_rotate(RBRoot *root, Node *y)
|
||||||
|
{
|
||||||
|
Node *x = y->left;
|
||||||
|
y->left = x->right;
|
||||||
|
if (x->right != NULL)
|
||||||
|
x->right->parent = y;
|
||||||
|
x->parent = y->parent;
|
||||||
|
|
||||||
|
if (y->parent == NULL)
|
||||||
|
{
|
||||||
|
root->node = x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (y == y->parent->right)
|
||||||
|
y->parent->right = x;
|
||||||
|
else
|
||||||
|
y->parent->left = x;
|
||||||
|
}
|
||||||
|
x->right = y;
|
||||||
|
y->parent = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 红黑树插入修正函数
|
||||||
|
*/
|
||||||
|
static void rbtree_insert_fixup(RBRoot *root, Node *node)
|
||||||
|
{
|
||||||
|
Node *parent, *gparent;
|
||||||
|
|
||||||
|
// 若“父节点存在,并且父节点的颜色是红色”
|
||||||
|
while ((parent = rb_parent(node)) && rb_is_red(parent))
|
||||||
|
{
|
||||||
|
gparent = rb_parent(parent);
|
||||||
|
|
||||||
|
//若“父节点”是“祖父节点的左孩子”
|
||||||
|
if (parent == gparent->left)
|
||||||
|
{
|
||||||
|
// Case 1条件:叔叔节点是红色
|
||||||
|
{
|
||||||
|
Node *uncle = gparent->right;
|
||||||
|
if (uncle && rb_is_red(uncle))
|
||||||
|
{
|
||||||
|
rb_set_black(uncle);
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_red(gparent);
|
||||||
|
node = gparent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2条件:叔叔是黑色,且当前节点是右孩子
|
||||||
|
if (parent->right == node)
|
||||||
|
{
|
||||||
|
Node *tmp;
|
||||||
|
rbtree_left_rotate(root, parent);
|
||||||
|
tmp = parent;
|
||||||
|
parent = node;
|
||||||
|
node = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 3条件:叔叔是黑色,且当前节点是左孩子。
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_red(gparent);
|
||||||
|
rbtree_right_rotate(root, gparent);
|
||||||
|
}
|
||||||
|
else//若“z的父节点”是“z的祖父节点的右孩子”
|
||||||
|
{
|
||||||
|
// Case 1条件:叔叔节点是红色
|
||||||
|
{
|
||||||
|
Node *uncle = gparent->left;
|
||||||
|
if (uncle && rb_is_red(uncle))
|
||||||
|
{
|
||||||
|
rb_set_black(uncle);
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_red(gparent);
|
||||||
|
node = gparent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2条件:叔叔是黑色,且当前节点是左孩子
|
||||||
|
if (parent->left == node)
|
||||||
|
{
|
||||||
|
Node *tmp;
|
||||||
|
rbtree_right_rotate(root, parent);
|
||||||
|
tmp = parent;
|
||||||
|
parent = node;
|
||||||
|
node = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 3条件:叔叔是黑色,且当前节点是右孩子。
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_red(gparent);
|
||||||
|
rbtree_left_rotate(root, gparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将根节点设为黑色
|
||||||
|
rb_set_black(root->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 添加节点
|
||||||
|
*/
|
||||||
|
static void rbtree_insert(RBRoot *root, Node *node)
|
||||||
|
{
|
||||||
|
Node *y = NULL;
|
||||||
|
Node *x = root->node;
|
||||||
|
while (x != NULL)
|
||||||
|
{
|
||||||
|
y = x;
|
||||||
|
if (node->key < x->key)
|
||||||
|
x = x->left;
|
||||||
|
else
|
||||||
|
x = x->right;
|
||||||
|
}
|
||||||
|
rb_parent(node) = y;
|
||||||
|
|
||||||
|
if (y != NULL)
|
||||||
|
{
|
||||||
|
if (node->key < y->key)
|
||||||
|
y->left = node;
|
||||||
|
else
|
||||||
|
y->right = node;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
root->node = node;
|
||||||
|
}
|
||||||
|
node->color = RED;
|
||||||
|
rbtree_insert_fixup(root, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 创建结点
|
||||||
|
*/
|
||||||
|
static Node* create_rbtree_node(Type key, Node *parent, Node *left, Node* right)
|
||||||
|
{
|
||||||
|
Node* p;
|
||||||
|
|
||||||
|
if ((p = (Node *)malloc(sizeof(Node))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
p->key = key;
|
||||||
|
p->left = left;
|
||||||
|
p->right = right;
|
||||||
|
p->parent = parent;
|
||||||
|
p->color = BLACK; // 默认为黑色
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 新建结点(节点键值为key),并将其插入到红黑树中
|
||||||
|
*/
|
||||||
|
int insert_rbtree(RBRoot *root, Type key)
|
||||||
|
{
|
||||||
|
Node *node;
|
||||||
|
if (search(root->node, key) != NULL)
|
||||||
|
return -1;
|
||||||
|
if ((node=create_rbtree_node(key, NULL, NULL, NULL)) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rbtree_insert(root, node);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 红黑树删除修正函数
|
||||||
|
*/
|
||||||
|
static void rbtree_delete_fixup(RBRoot *root, Node *node, Node *parent)
|
||||||
|
{
|
||||||
|
Node *other;
|
||||||
|
|
||||||
|
while ((!node || rb_is_black(node)) && node != root->node)
|
||||||
|
{
|
||||||
|
if (parent->left == node)
|
||||||
|
{
|
||||||
|
other = parent->right;
|
||||||
|
if (rb_is_red(other))
|
||||||
|
{
|
||||||
|
rb_set_black(other);
|
||||||
|
rb_set_red(parent);
|
||||||
|
rbtree_left_rotate(root, parent);
|
||||||
|
other = parent->right;
|
||||||
|
}
|
||||||
|
if ((!other->left || rb_is_black(other->left)) &&
|
||||||
|
(!other->right || rb_is_black(other->right)))
|
||||||
|
{
|
||||||
|
rb_set_red(other);
|
||||||
|
node = parent;
|
||||||
|
parent = rb_parent(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!other->right || rb_is_black(other->right))
|
||||||
|
{
|
||||||
|
rb_set_black(other->left);
|
||||||
|
rb_set_red(other);
|
||||||
|
rbtree_right_rotate(root, other);
|
||||||
|
other = parent->right;
|
||||||
|
}
|
||||||
|
rb_set_color(other, rb_color(parent));
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_black(other->right);
|
||||||
|
rbtree_left_rotate(root, parent);
|
||||||
|
node = root->node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
other = parent->left;
|
||||||
|
if (rb_is_red(other))
|
||||||
|
{
|
||||||
|
rb_set_black(other);
|
||||||
|
rb_set_red(parent);
|
||||||
|
rbtree_right_rotate(root, parent);
|
||||||
|
other = parent->left;
|
||||||
|
}
|
||||||
|
if ((!other->left || rb_is_black(other->left)) &&
|
||||||
|
(!other->right || rb_is_black(other->right)))
|
||||||
|
{
|
||||||
|
rb_set_red(other);
|
||||||
|
node = parent;
|
||||||
|
parent = rb_parent(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!other->left || rb_is_black(other->left))
|
||||||
|
{
|
||||||
|
// Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
|
||||||
|
rb_set_black(other->right);
|
||||||
|
rb_set_red(other);
|
||||||
|
rbtree_left_rotate(root, other);
|
||||||
|
other = parent->left;
|
||||||
|
}
|
||||||
|
// Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
|
||||||
|
rb_set_color(other, rb_color(parent));
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_black(other->left);
|
||||||
|
rbtree_right_rotate(root, parent);
|
||||||
|
node = root->node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node)
|
||||||
|
rb_set_black(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 删除结点
|
||||||
|
*/
|
||||||
|
void rbtree_delete(RBRoot *root, Node *node)
|
||||||
|
{
|
||||||
|
Node *child, *parent;
|
||||||
|
int color;
|
||||||
|
if ( (node->left!=NULL) && (node->right!=NULL) )
|
||||||
|
{
|
||||||
|
Node *replace = node;
|
||||||
|
replace = replace->right;
|
||||||
|
while (replace->left != NULL)
|
||||||
|
replace = replace->left;
|
||||||
|
if (rb_parent(node))
|
||||||
|
{
|
||||||
|
if (rb_parent(node)->left == node)
|
||||||
|
rb_parent(node)->left = replace;
|
||||||
|
else
|
||||||
|
rb_parent(node)->right = replace;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
root->node = replace;
|
||||||
|
child = replace->right;
|
||||||
|
parent = rb_parent(replace);
|
||||||
|
color = rb_color(replace);
|
||||||
|
if (parent == node)
|
||||||
|
{
|
||||||
|
parent = replace;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (child)
|
||||||
|
rb_set_parent(child, parent);
|
||||||
|
parent->left = child;
|
||||||
|
|
||||||
|
replace->right = node->right;
|
||||||
|
rb_set_parent(node->right, replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
replace->parent = node->parent;
|
||||||
|
replace->color = node->color;
|
||||||
|
replace->left = node->left;
|
||||||
|
node->left->parent = replace;
|
||||||
|
|
||||||
|
if (color == BLACK)
|
||||||
|
rbtree_delete_fixup(root, child, parent);
|
||||||
|
free(node);
|
||||||
|
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->left !=NULL)
|
||||||
|
child = node->left;
|
||||||
|
else
|
||||||
|
child = node->right;
|
||||||
|
|
||||||
|
parent = node->parent;
|
||||||
|
color = node->color;
|
||||||
|
|
||||||
|
if (child)
|
||||||
|
child->parent = parent;
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
if (parent->left == node)
|
||||||
|
parent->left = child;
|
||||||
|
else
|
||||||
|
parent->right = child;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
root->node = child;
|
||||||
|
|
||||||
|
if (color == BLACK)
|
||||||
|
rbtree_delete_fixup(root, child, parent);
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 删除键值为key的结点
|
||||||
|
*/
|
||||||
|
void delete_rbtree(RBRoot *root, Type key)
|
||||||
|
{
|
||||||
|
Node *z, *node;
|
||||||
|
|
||||||
|
if ((z = search(root->node, key)) != NULL)
|
||||||
|
rbtree_delete(root, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 销毁红黑树
|
||||||
|
*/
|
||||||
|
static void rbtree_destroy(RBTree tree)
|
||||||
|
{
|
||||||
|
if (tree==NULL)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if (tree->left != NULL)
|
||||||
|
rbtree_destroy(tree->left);
|
||||||
|
if (tree->right != NULL)
|
||||||
|
rbtree_destroy(tree->right);
|
||||||
|
|
||||||
|
free(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_rbtree(RBRoot *root)
|
||||||
|
{
|
||||||
|
if (root != NULL)
|
||||||
|
rbtree_destroy(root->node);
|
||||||
|
|
||||||
|
free(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 打印"红黑树"
|
||||||
|
*/
|
||||||
|
static void rbtree_print(RBTree tree, Type key, int direction)
|
||||||
|
{
|
||||||
|
if(tree != NULL)
|
||||||
|
{
|
||||||
|
if(direction==0) // tree是根节点
|
||||||
|
printf("%2d(B) is root\n", tree->key);
|
||||||
|
else // tree是分支节点
|
||||||
|
printf("%2d(%s) is %2d's %6s child\n", tree->key, rb_is_red(tree)?"R":"B", key, direction==1?"right" : "left");
|
||||||
|
|
||||||
|
rbtree_print(tree->left, tree->key, -1);
|
||||||
|
rbtree_print(tree->right,tree->key, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_rbtree(RBRoot *root)
|
||||||
|
{
|
||||||
|
if (root!=NULL && root->node!=NULL)
|
||||||
|
rbtree_print(root->node, root->node->key, 0);
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef _RED_BLACK_TREE_H_
|
||||||
|
#define _RED_BLACK_TREE_H_
|
||||||
|
|
||||||
|
#define RED 0 // 红色节点
|
||||||
|
#define BLACK 1 // 黑色节点
|
||||||
|
|
||||||
|
typedef int Type;
|
||||||
|
|
||||||
|
// 红黑树的节点
|
||||||
|
typedef struct RBTreeNode{
|
||||||
|
unsigned char color; // 颜色(RED 或 BLACK)
|
||||||
|
Type key; // 关键字(键值)
|
||||||
|
struct RBTreeNode *left; // 左孩子
|
||||||
|
struct RBTreeNode *right; // 右孩子
|
||||||
|
struct RBTreeNode *parent; // 父结点
|
||||||
|
}Node, *RBTree;
|
||||||
|
|
||||||
|
// 红黑树的根
|
||||||
|
typedef struct rb_root{
|
||||||
|
Node *node;
|
||||||
|
}RBRoot;
|
||||||
|
|
||||||
|
// 创建红黑树,返回"红黑树的根"!
|
||||||
|
RBRoot* create_rbtree();
|
||||||
|
|
||||||
|
// 销毁红黑树
|
||||||
|
void destroy_rbtree(RBRoot *root);
|
||||||
|
|
||||||
|
// 将结点插入到红黑树中。插入成功,返回0;失败返回-1。
|
||||||
|
int insert_rbtree(RBRoot *root, Type key);
|
||||||
|
|
||||||
|
// 删除结点(key为节点的值)
|
||||||
|
void delete_rbtree(RBRoot *root, Type key);
|
||||||
|
|
||||||
|
|
||||||
|
// 前序遍历"红黑树"
|
||||||
|
void preorder_rbtree(RBRoot *root);
|
||||||
|
// 中序遍历"红黑树"
|
||||||
|
void inorder_rbtree(RBRoot *root);
|
||||||
|
// 后序遍历"红黑树"
|
||||||
|
void postorder_rbtree(RBRoot *root);
|
||||||
|
|
||||||
|
// (递归实现)查找"红黑树"中键值为key的节点。找到的话,返回0;否则,返回-1。
|
||||||
|
int rbtree_search(RBRoot *root, Type key);
|
||||||
|
// (非递归实现)查找"红黑树"中键值为key的节点。找到的话,返回0;否则,返回-1。
|
||||||
|
int iterative_rbtree_search(RBRoot *root, Type key);
|
||||||
|
|
||||||
|
// 返回最小结点的值(将值保存到val中)。找到的话,返回0;否则返回-1。
|
||||||
|
int rbtree_minimum(RBRoot *root, int *val);
|
||||||
|
// 返回最大结点的值(将值保存到val中)。找到的话,返回0;否则返回-1。
|
||||||
|
int rbtree_maximum(RBRoot *root, int *val);
|
||||||
|
|
||||||
|
// 打印红黑树
|
||||||
|
void print_rbtree(RBRoot *root);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,341 +1,64 @@
|
||||||
/*
|
#include <stdio.h>
|
||||||
* Copyright (c) 2023 AIIT XUOS Lab
|
#include "rbtree.h"
|
||||||
* XiUOS is licensed under Mulan PSL v2.
|
#include "rbtree.c"
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
#define IF_INSERT 1 // "插入节点"flag
|
||||||
* @file: test_rbtree.c
|
#define IF_DELETE 1 // "删除节点"flag
|
||||||
* @brief: a application of red-black tree function
|
#define LENGTH(a) ( (sizeof(a)) / (sizeof(a[0])) )
|
||||||
* @version: 1.0
|
|
||||||
* @author: AIIT XUOS Lab
|
|
||||||
* @date: 2023/6/23
|
|
||||||
*/
|
|
||||||
#include<string.h>
|
|
||||||
#include <transform.h>
|
|
||||||
#include"test_rbtree.h"
|
|
||||||
#ifdef ADD_XIZI_FEATURES
|
|
||||||
|
|
||||||
void RBTreeTraversal(RBTreeType *tree, RBNodeType *node)
|
void main()
|
||||||
{
|
{
|
||||||
if (node != tree->leaf) {
|
int a[] = {10, 150, 70, 0, 190, 270, 20, 50, 80};
|
||||||
RBTreeTraversal(tree, node->left_child);
|
int i, ilen=LENGTH(a);
|
||||||
printf("key:%d, color:%s\n", node->key, (node->is_red ? "Red" : "Black"));
|
RBRoot *root=NULL;
|
||||||
RBTreeTraversal(tree, node->right_child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RBNodeType* RBTreeSearch(RBTreeType *tree, int key)
|
root = create_rbtree();
|
||||||
{
|
printf("red black tree 原始数据: ");
|
||||||
RBNodeType* current_node = tree->root;
|
for(i=0; i<ilen; i++)
|
||||||
while (current_node != tree->leaf){
|
printf("%d ", a[i]);
|
||||||
if (key < current_node->key)
|
printf("\n");
|
||||||
current_node = current_node->left_child;
|
|
||||||
else if (key > current_node->key)
|
for(i=0; i<ilen; i++)
|
||||||
current_node = current_node->right_child;
|
{
|
||||||
else
|
insert_rbtree(root, a[i]);
|
||||||
return current_node;
|
#if IF_INSERT
|
||||||
|
printf("添加节点: %d\n", a[i]);
|
||||||
|
printf("树的结构信息: \n");
|
||||||
|
print_rbtree(root);
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree->leaf;
|
if (rbtree_minimum(root, &i)==0)
|
||||||
}
|
printf("最小值: %d\n", i);
|
||||||
|
if (rbtree_maximum(root, &i)==0)
|
||||||
|
printf("最大值: %d\n", i);
|
||||||
|
printf("树的结构信息: \n");
|
||||||
|
|
||||||
void RBTreeLeftRotate(RBTreeType *tree, RBNodeType *current_node)
|
printf("== 前序遍历: ");
|
||||||
{
|
preorder_rbtree(root);
|
||||||
RBNodeType* child_node = current_node->right_child;
|
|
||||||
|
|
||||||
current_node->right_child = child_node->left_child;
|
printf("\n== 中序遍历: ");
|
||||||
if (child_node->left_child != tree->leaf)
|
inorder_rbtree(root);
|
||||||
child_node->left_child->parent = current_node;
|
|
||||||
|
|
||||||
child_node->parent = current_node->parent;
|
printf("\n== 后序遍历: ");
|
||||||
if (current_node->parent == tree->leaf)
|
postorder_rbtree(root);
|
||||||
tree->root = child_node;
|
printf("\n");
|
||||||
else if (current_node == current_node->parent->left_child)
|
|
||||||
current_node->parent->left_child = child_node;
|
|
||||||
else
|
|
||||||
current_node->parent->right_child = child_node;
|
|
||||||
|
|
||||||
child_node->left_child = current_node;
|
|
||||||
current_node->parent = child_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RBTreeRightRotate(RBTreeType *tree, RBNodeType* current_node)
|
#if IF_DELETE
|
||||||
{
|
for(i=0; i<ilen; i++)
|
||||||
RBNodeType* child_node = current_node->left_child;
|
{
|
||||||
|
delete_rbtree(root, a[i]);
|
||||||
|
|
||||||
current_node->left_child = child_node->right_child;
|
printf("== 删除节点: %d\n", a[i]);
|
||||||
if (child_node->right_child != tree->leaf)
|
if (root)
|
||||||
child_node->right_child->parent = current_node;
|
{
|
||||||
|
printf("== 树的详细信息: \n");
|
||||||
child_node->parent = current_node->parent;
|
print_rbtree(root);
|
||||||
if (current_node->parent == tree->leaf)
|
printf("\n");
|
||||||
tree->root = child_node;
|
|
||||||
else if (current_node == current_node->parent->right_child)
|
|
||||||
current_node->parent->right_child = child_node;
|
|
||||||
else
|
|
||||||
current_node->parent->left_child = child_node;
|
|
||||||
|
|
||||||
child_node->right_child = current_node;
|
|
||||||
current_node->parent = child_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InsertFixup(RBTreeType *tree, RBNodeType* current_node)
|
|
||||||
{
|
|
||||||
while (current_node->parent->is_red){
|
|
||||||
/* The parent of current_node is the left subtree of the grandfather */
|
|
||||||
if (current_node->parent == current_node->parent->parent->left_child){
|
|
||||||
RBNodeType * uncle_node = current_node->parent->parent->right_child;
|
|
||||||
if (uncle_node->is_red){ /* case1:red uncle and red parent, change color */
|
|
||||||
uncle_node->is_red = false;
|
|
||||||
current_node->parent->is_red = false;
|
|
||||||
current_node->parent->parent->is_red = true;
|
|
||||||
|
|
||||||
current_node = current_node->parent->parent;
|
|
||||||
}else{ /* case2:black uncle and red parent, need rotation */
|
|
||||||
if (current_node->parent->right_child == current_node){
|
|
||||||
current_node = current_node->parent;
|
|
||||||
RBTreeLeftRotate(tree, current_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
current_node->parent->is_red = false;
|
|
||||||
current_node->parent->parent->is_red = true;
|
|
||||||
RBTreeRightRotate(tree, current_node->parent->parent);
|
|
||||||
}
|
|
||||||
/* The parent of current_node is the right subtree of the grandfather, same with left subtree */
|
|
||||||
}else{
|
|
||||||
RBNodeType * uncle_node = current_node->parent->parent->left_child;
|
|
||||||
if (uncle_node->is_red){
|
|
||||||
uncle_node->is_red = false;
|
|
||||||
current_node->parent->is_red = false;
|
|
||||||
current_node->parent->parent->is_red = true;
|
|
||||||
|
|
||||||
current_node = current_node->parent->parent;
|
|
||||||
}else{
|
|
||||||
if (current_node->parent->left_child == current_node){
|
|
||||||
current_node = current_node->parent;
|
|
||||||
RBTreeRightRotate(tree, current_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
current_node->parent->is_red = false;
|
|
||||||
current_node->parent->parent->is_red = true;
|
|
||||||
RBTreeLeftRotate(tree, current_node->parent->parent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
tree->root->is_red = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RBTreeInsert(RBTreeType *tree, RBNodeType* new_node)
|
destroy_rbtree(root);
|
||||||
{
|
}
|
||||||
RBNodeType* previous_node = tree->root;
|
|
||||||
RBNodeType* current_node = tree->root;
|
|
||||||
|
|
||||||
while (current_node != tree->leaf){
|
|
||||||
previous_node = current_node;
|
|
||||||
if (new_node->key > current_node->key)
|
|
||||||
current_node = current_node->right_child;
|
|
||||||
else if (new_node->key < current_node->key)
|
|
||||||
current_node = current_node->left_child;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previous_node == tree->leaf){
|
|
||||||
tree->root = new_node;
|
|
||||||
tree->root->parent = tree->leaf;
|
|
||||||
}else{
|
|
||||||
new_node->parent = previous_node;
|
|
||||||
|
|
||||||
if (previous_node->key > new_node->key)
|
|
||||||
previous_node->left_child = new_node;
|
|
||||||
else
|
|
||||||
previous_node->right_child = new_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
InsertFixup(tree, new_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
RBNodeType* FindSuccessor(RBTreeType *tree, RBNodeType* current_node)
|
|
||||||
{
|
|
||||||
RBNodeType* parent_node = current_node->parent;
|
|
||||||
if (current_node->right_child != tree->leaf){
|
|
||||||
current_node = current_node->right_child;
|
|
||||||
while (current_node->left_child != tree->leaf)
|
|
||||||
current_node = current_node->left_child;
|
|
||||||
return current_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((parent_node != tree->leaf) && (current_node == parent_node->right_child)){
|
|
||||||
current_node = parent_node;
|
|
||||||
parent_node = parent_node->parent;
|
|
||||||
}
|
|
||||||
return parent_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteFixup(RBTreeType *tree, RBNodeType* current_node)
|
|
||||||
{
|
|
||||||
while ((current_node != tree->root) && (current_node->is_red == false)){
|
|
||||||
if (current_node == current_node->parent->left_child){
|
|
||||||
|
|
||||||
RBNodeType* brother_node = current_node->parent->right_child;
|
|
||||||
if (brother_node->is_red){
|
|
||||||
brother_node->is_red = false;
|
|
||||||
current_node->parent->is_red = true;
|
|
||||||
RBTreeLeftRotate(tree, current_node->parent);
|
|
||||||
brother_node = current_node->parent->right_child;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((brother_node->left_child->is_red == false) && (brother_node->right_child->is_red == false)){
|
|
||||||
brother_node->is_red = true;
|
|
||||||
current_node = current_node->parent;
|
|
||||||
}else{
|
|
||||||
if (brother_node->right_child->is_red == false){
|
|
||||||
brother_node->left_child->is_red = false;
|
|
||||||
brother_node->is_red = true;
|
|
||||||
RBTreeRightRotate(tree, brother_node);
|
|
||||||
brother_node = current_node->parent->right_child;
|
|
||||||
}
|
|
||||||
|
|
||||||
brother_node->is_red = current_node->parent->is_red;
|
|
||||||
current_node->parent->is_red = false;
|
|
||||||
brother_node->right_child->is_red = false;
|
|
||||||
RBTreeLeftRotate(tree, current_node->parent);
|
|
||||||
current_node = tree->root;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
RBNodeType* brother_node = current_node->parent->left_child;
|
|
||||||
if (brother_node->is_red){
|
|
||||||
brother_node->is_red = false;
|
|
||||||
current_node->parent->is_red = true;
|
|
||||||
RBTreeRightRotate(tree, current_node->parent);
|
|
||||||
brother_node = current_node->parent->left_child;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((brother_node->left_child->is_red == false) && (brother_node->right_child->is_red == false)){
|
|
||||||
brother_node->is_red = true;
|
|
||||||
current_node = current_node->parent;
|
|
||||||
}else{
|
|
||||||
if (brother_node->left_child->is_red == false){
|
|
||||||
brother_node->right_child->is_red = false;
|
|
||||||
brother_node->is_red = true;
|
|
||||||
RBTreeLeftRotate(tree, brother_node);
|
|
||||||
brother_node = current_node->parent->left_child;
|
|
||||||
}
|
|
||||||
|
|
||||||
brother_node->is_red = current_node->parent->is_red;
|
|
||||||
current_node->parent->is_red = false;
|
|
||||||
brother_node->left_child->is_red = false;
|
|
||||||
RBTreeRightRotate(tree, current_node->parent);
|
|
||||||
current_node = tree->root;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current_node->is_red = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RBTreeDelete(RBTreeType *tree, RBNodeType* target_node)
|
|
||||||
{
|
|
||||||
RBNodeType* delete_node = tree->leaf;
|
|
||||||
RBNodeType* replace_node = tree->leaf;
|
|
||||||
|
|
||||||
if ((target_node->left_child == tree->leaf) || (target_node->right_child == tree->leaf))
|
|
||||||
delete_node = target_node;
|
|
||||||
else
|
|
||||||
delete_node = FindSuccessor(tree, target_node);
|
|
||||||
|
|
||||||
if (delete_node->left_child != tree->leaf) /* successor still has subtree */
|
|
||||||
replace_node = delete_node->left_child;
|
|
||||||
else if (delete_node->right_child != tree->leaf)
|
|
||||||
replace_node = delete_node->right_child;
|
|
||||||
|
|
||||||
replace_node->parent = delete_node->parent;
|
|
||||||
|
|
||||||
if (delete_node->parent == tree->leaf) /* delete a root node */
|
|
||||||
tree->root = replace_node;
|
|
||||||
else if (delete_node == delete_node->parent->left_child)
|
|
||||||
delete_node->parent->left_child = replace_node;
|
|
||||||
else
|
|
||||||
delete_node->parent->right_child = replace_node;
|
|
||||||
|
|
||||||
if (delete_node != target_node)
|
|
||||||
target_node->key = delete_node->key;
|
|
||||||
|
|
||||||
if (delete_node->is_red == false)
|
|
||||||
DeleteFixup(tree, replace_node);
|
|
||||||
|
|
||||||
free(delete_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TestRBTree(void)
|
|
||||||
{
|
|
||||||
int default_key[] = { 16, 25, 23, 5, 2, 6, 17, 37, 38, 98, 20, 19, 47, 49, 12, 21, 9, 18, 14, 15 };
|
|
||||||
int array_size = sizeof(default_key) / sizeof(default_key[0]);
|
|
||||||
|
|
||||||
printf("Test Red Black Tree\n");
|
|
||||||
printf("default_key array: ");
|
|
||||||
for (int i = 0; i < array_size; i++)
|
|
||||||
printf("%d ", default_key[i]);
|
|
||||||
printf("\n%d elements\n", array_size);
|
|
||||||
|
|
||||||
RBTreeType *tree = (RBTreeType *)malloc(sizeof(RBTreeType));
|
|
||||||
if (tree == NULL) {
|
|
||||||
printf("malloc failed\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tree->leaf = (RBNodeType*)malloc(sizeof(RBNodeType));
|
|
||||||
tree->leaf->left_child = NULL;
|
|
||||||
tree->leaf->right_child = NULL;
|
|
||||||
tree->leaf->parent = NULL;
|
|
||||||
tree->leaf->is_red = false;
|
|
||||||
tree->leaf->key = -1;
|
|
||||||
tree->root = tree->leaf;
|
|
||||||
|
|
||||||
RBNodeType *node = tree->leaf;
|
|
||||||
|
|
||||||
for (int i = 0; i < array_size; i++) {
|
|
||||||
node = (RBNodeType*)malloc(sizeof(RBNodeType));
|
|
||||||
node->left_child = tree->leaf;
|
|
||||||
node->right_child = tree->leaf;
|
|
||||||
node->parent = NULL;
|
|
||||||
node->is_red = true;
|
|
||||||
node->key = default_key[i];
|
|
||||||
printf("insert key[%d]=%d\n",i,default_key[i]);
|
|
||||||
RBTreeInsert(tree, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("------------------Inorder Traversal------------------\n");
|
|
||||||
RBTreeTraversal(tree, tree->root);
|
|
||||||
|
|
||||||
for (int i = 0; i < array_size; i++) {
|
|
||||||
printf("search key = %d\n", default_key[i]);
|
|
||||||
node = RBTreeSearch(tree, default_key[i]);
|
|
||||||
printf("search succeeded, parent node: %d, left-child: %d, right-child: %d\n", node->parent->key, node->left_child->key, node->right_child->key);
|
|
||||||
|
|
||||||
printf("delete key = %d\n", node->key);
|
|
||||||
RBTreeDelete(tree, node);
|
|
||||||
|
|
||||||
printf("Show current tree?Y/N \n");
|
|
||||||
char ch;
|
|
||||||
scanf("%c", &ch);
|
|
||||||
if (ch == 'Y' || ch == 'y') {
|
|
||||||
printf("------------------Inorder Traversal Tree After Deletion------------------\n");
|
|
||||||
if (tree->root != tree->leaf)
|
|
||||||
RBTreeTraversal(tree, tree->root);
|
|
||||||
else
|
|
||||||
printf("the tree is empty.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PRIV_SHELL_CMD_FUNCTION(TestRBTree, a red-black tree test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 AIIT XUOS Lab
|
|
||||||
* XiUOS is licensed under Mulan PSL v2.
|
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file: test_rbtree.h
|
|
||||||
* @brief: a head file of red-black tree structure
|
|
||||||
* @version: 1.0
|
|
||||||
* @author: AIIT XUOS Lab
|
|
||||||
* @date: 2023/6/23
|
|
||||||
*/
|
|
||||||
#ifndef REDBLACKTREE_H_
|
|
||||||
#define REDBLACKTREE_H_
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
typedef struct RedBlackNode
|
|
||||||
{
|
|
||||||
int key;
|
|
||||||
struct RedBlackNode *left_child;
|
|
||||||
struct RedBlackNode *right_child;
|
|
||||||
struct RedBlackNode *parent;
|
|
||||||
bool is_red;
|
|
||||||
} RBNodeType;
|
|
||||||
|
|
||||||
typedef struct RedBlackTree
|
|
||||||
{
|
|
||||||
RBNodeType *root;
|
|
||||||
RBNodeType *leaf;
|
|
||||||
} RBTreeType;
|
|
||||||
|
|
||||||
void TestRBTree(void);
|
|
||||||
|
|
||||||
void RBTreeTraversal(RBTreeType *tree, RBNodeType *node);
|
|
||||||
|
|
||||||
void RBTreeLeftRotate(RBTreeType *tree, RBNodeType *current_node);
|
|
||||||
|
|
||||||
void RBTreeRightRotate(RBTreeType *tree, RBNodeType* current_node);
|
|
||||||
|
|
||||||
void InsertFixup(RBTreeType *tree, RBNodeType* current_node);
|
|
||||||
|
|
||||||
void RBTreeInsert(RBTreeType *tree, RBNodeType* new_node);
|
|
||||||
|
|
||||||
void DeleteFixup(RBTreeType *tree, RBNodeType* current_node);
|
|
||||||
|
|
||||||
void RBTreeDelete(RBTreeType *tree, RBNodeType* target_node);
|
|
||||||
|
|
||||||
RBNodeType* FindSuccessor(RBTreeType *tree, RBNodeType* current_node);
|
|
||||||
|
|
||||||
RBNodeType* RBTreeSearch(RBTreeType *tree, int key);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,32 +1,32 @@
|
||||||
/*
|
// /*
|
||||||
* Copyright (c) 2020 AIIT XUOS Lab
|
// * Copyright (c) 2020 AIIT XUOS Lab
|
||||||
* XiUOS is licensed under Mulan PSL v2.
|
// * XiUOS is licensed under Mulan PSL v2.
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
// * You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
// * You may obtain a copy of Mulan PSL v2 at:
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
// * http://license.coscl.org.cn/MulanPSL2
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
// * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
// * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
// * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
* See the Mulan PSL v2 for more details.
|
// * See the Mulan PSL v2 for more details.
|
||||||
*/
|
// */
|
||||||
|
|
||||||
#include <stdio.h>
|
// #include <stdio.h>
|
||||||
#include <string.h>
|
// #include <string.h>
|
||||||
// #include <user_api.h>
|
// // #include <user_api.h>
|
||||||
#include <transform.h>
|
// #include <transform.h>
|
||||||
|
|
||||||
|
|
||||||
extern int FrameworkInit();
|
// extern int FrameworkInit();
|
||||||
extern void ApplicationOtaTaskInit(void);
|
// extern void ApplicationOtaTaskInit(void);
|
||||||
int main(void)
|
// int main(void)
|
||||||
{
|
// {
|
||||||
printf("Hello, world! \n");
|
// printf("Hello, world! \n");
|
||||||
FrameworkInit();
|
// FrameworkInit();
|
||||||
#ifdef APPLICATION_OTA
|
// #ifdef APPLICATION_OTA
|
||||||
ApplicationOtaTaskInit();
|
// ApplicationOtaTaskInit();
|
||||||
#endif
|
// #endif
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
// int cppmain(void);
|
// // int cppmain(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue