unicstl/src/tree.c
2025-06-20 11:14:59 +08:00

1525 lines
36 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file tree.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2024-06-23
*
* @copyright Copyright (c) 2024
*
*/
#include "tree.h"
#include "queue.h"
#include "stack.h"
// #define TREE_RECURSIVE_ENABLED
static struct _tree_node* tree_node_new(struct _tree* self, void* obj)
{
assert(self != NULL);
void* obj_new = malloc(self->_obj_size);
if (obj_new == NULL)
{
return NULL;
}
memmove(obj_new, obj, self->_obj_size);
struct _tree_node* node_new = (struct _tree_node*)malloc(sizeof(struct _tree_node));
if (node_new == NULL)
{
free(obj_new);
return NULL;
}
node_new->obj = obj_new;
node_new->parent = NULL;
node_new->left = NULL;
node_new->right = NULL;
node_new->balance = 0;
return node_new;
}
static void tree_node_free(struct _tree_node** node)
{
if (node != NULL && (*node) != NULL)
{
if ((*node)->obj != NULL)
{
free((*node)->obj);
}
free(*node);
*node = NULL;
}
}
static uint32_t tree_height_node(struct _tree* self, struct _tree_node* root)
{
#ifdef TREE_RECURSIVE_ENABLED
assert(self != NULL);
if (root == NULL)
{
return 0;
}
uint32_t left_height = tree_height_node(self, root->left);
uint32_t right_height = tree_height_node(self, root->right);
return (left_height > right_height) ? (left_height + 1) : (right_height + 1);
#else
assert(self != NULL);
if (root == NULL)
{
return 0;
}
uint32_t height = 0;
uint32_t count_cur_level = 0;
uint32_t count_next_level = 0;
struct _tree_node* node = root;
queue_t queue = queue_new(sizeof(struct _tree_node*));
queue->push(queue, &node);
while (!queue->empty(queue))
{
queue->pop(queue, &node);
if (node->left != NULL)
{
queue->push(queue, &node->left);
}
if (node->right != NULL)
{
queue->push(queue, &node->right);
}
if (count_cur_level == count_next_level)
{
count_next_level = queue->size(queue);
height++;
count_cur_level = 1;
}
else
{
count_cur_level++;
}
}
queue_free(&queue);
return height;
#endif
}
static void tree_set_balance(struct _tree* self, struct _tree_node* node)
{
assert(self != NULL);
if (node == NULL)
{
return;
}
node->balance = (int32_t)(tree_height_node(self, node->right) - tree_height_node(self, node->left));
}
static struct _tree_node* tree_turn_left(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
struct _tree_node* node = root->right;
if (node == NULL)
{
return root;
}
if (root->parent == NULL)
{
self->_root = node; // step1
}
else
{
if (root->parent->left == root)
{
root->parent->left = node; // step1
}
else if (root->parent->right == root)
{
root->parent->right = node; // setp1
}
}
node->parent = root->parent; // step2
root->parent = node; // step3
root->right = node->left; // step4
if (node->left != NULL)
{
node->left->parent = root; // step5
}
node->left = root; // step6
tree_set_balance(self, root);
tree_set_balance(self, node);
return node;
}
static struct _tree_node* tree_turn_right(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
struct _tree_node* node = root->left;
if (node == NULL)
{
return root;
}
if (root->parent == NULL)
{
self->_root = node; // step1
}
else
{
if (root->parent->left == root)
{
root->parent->left = node; // step1
}
else if (root->parent->right == root)
{
root->parent->right = node; // setp1
}
}
node->parent = root->parent; // step2
root->parent = node; // step3
root->left = node->right; // step4
if (node->right != NULL)
{
node->right->parent = root; // step5
}
node->right = root; // step6
tree_set_balance(self, root);
tree_set_balance(self, node);
return node;
}
static struct _tree_node* tree_turn_left_then_right(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
struct _tree_node* node = root->left;
if (node != NULL)
{
tree_turn_left(self, node);
}
node = tree_turn_right(self, root);
return node;
}
static struct _tree_node* tree_turn_right_then_left(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
struct _tree_node* node = root->right;
if (node != NULL)
{
tree_turn_right(self, node);
}
node = tree_turn_left(self, root);
return node;
}
/**
* @brief
*
* if balance = rigth - leftso
*
* | case | root->balance | node->balance | function |
* | ---- | ------------ | -------------- | -------- |
* | 1 | 2 | >= 0 | left rotation
* | 2 | 2 | < 0 | first right rotation, then left rotation
* | 3 | -2 | <= 0 | right rotation
* | 4 | -2 | > 0 | forth left rotation, then right rotation
*
* @param self
* @return true
* @return false
*/
static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
{
#ifdef TREE_RECURSIVE_ENABLED
assert(self != NULL);
if (root == NULL)
{
return false;
}
if (root->left == NULL && root->right == NULL)
{
return false;
}
tree_set_balance(self, root);
int balance = root->balance;
if (balance == 2)
{
if (root->right->balance >= 0)
{
root = tree_turn_left(self, root);
}
else
{
root = tree_turn_right_then_left(self, root);
}
}
else if (balance == -2)
{
if (root->left->balance <= 0)
{
root = tree_turn_right(self, root);
}
else
{
root = tree_turn_left_then_right(self, root);
}
}
if (root->parent != NULL)
{
tree_avl_rebalance(self, root->parent);
}
else
{
self->_root = root;
}
return true;
#else
assert(self != NULL);
if (root == NULL)
{
return false;
}
if (root->left == NULL && root->right == NULL)
{
return false;
}
int balance = 0;
do
{
tree_set_balance(self, root);
balance = root->balance;
if (balance == 2)
{
if (root->right->balance >= 0)
{
root = tree_turn_left(self, root);
}
else
{
root = tree_turn_right_then_left(self, root);
}
}
else if (balance == -2)
{
if (root->left->balance <= 0)
{
root = tree_turn_right(self, root);
}
else
{
root = tree_turn_left_then_right(self, root);
}
}
// if node become the new root
if (root->parent == NULL)
{
break;
}
root = root->parent;
} while (root != NULL);
self->_root = root;
return true;
#endif
}
static struct _tree_node* tree_find(struct _tree* self, void* obj)
{
assert(self != NULL);
struct _tree_node* root = self->_root;
while (root != NULL)
{
if (self->compare(obj, root->obj) == 0)
{
return root;
}
else if (self->compare(obj, root->obj) < 0)
{
root = root->left;
}
else
{
root = root->right;
}
}
return NULL;
}
static struct _tree_node* tree_find_min(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
while (root != NULL)
{
if (root->left == NULL)
{
break;
}
root = root->left;
}
return root;
}
static struct _tree_node* tree_find_max(struct _tree* self, struct _tree_node* root)
{
while (root != NULL)
{
if (root->right == NULL)
{
break;
}
root = root->right;
}
return root;
}
/**
* @brief find the position to insert or find object
*
* @param self
* @param obj
*/
struct _tree_node* tree_find_pos(struct _tree* self, void* obj)
{
assert(self != NULL);
assert(self->compare != NULL);
struct _tree_node* root = self->_root;
while (root != NULL)
{
if (self->compare(obj, root->obj) < 0)
{
if (root->left == NULL)
{
break;
}
root = root->left;
}
else if(self->compare(obj, root->obj) > 0)
{
if (root->right == NULL)
{
break;
}
root = root->right;
}
else
{
// if obj exist
break;
}
}
return root;
}
static bool tree_avl_insert(struct _tree* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
assert(self->compare != NULL);
if (self->_root == NULL)
{
// if tree is empty
struct _tree_node* new_node = tree_node_new(self, obj);
if (new_node == NULL)
{
return false;
}
self->_root = new_node;
}
else
{
struct _tree_node* root = tree_find_pos(self, obj);
if (self->compare(obj, root->obj) == 0)
{
// if obj is exist in tree, return false
return false;
}
struct _tree_node* new_node = tree_node_new(self, obj);
if (new_node == NULL)
{
return false;
}
if (self->compare(obj, root->obj) < 0)
{
root->left = new_node;
new_node->parent = root;
}
else /*if (self->compare(obj, root->obj) > 0)*/
{
root->right = new_node;
new_node->parent = root;
}
self->_rebalance(self, root);
}
self->_size++;
return true;
}
static bool tree_avl_delete_single_child(struct _tree* self, struct _tree_node* node)
{
assert(self != NULL);
assert(node != NULL);
if (node->parent == NULL)
{
if (node->left != NULL)
{
node->left->parent = node->parent; // step1 : NULL for root
self->_root = node->left; // step2
}
else if (node->right != NULL)
{
node->right->parent = node->parent; // step1 : NULL for root
self->_root = node->right; // step2
}
else
{
self->_root = NULL;
}
}
else
{
if (node->parent->left == node)
{
if (node->left != NULL)
{
node->left->parent = node->parent; // step1
node->parent->left = node->left; // step2
}
else if (node->right != NULL)
{
node->right->parent = node->parent; // step1
node->parent->left = node->right; // step2
}
else
{
node->parent->left = NULL;
}
}
else if (node->parent->right == node)
{
if (node->left != NULL)
{
node->left->parent = node->parent; // step1
node->parent->right = node->left; // step2
}
else if (node->right != NULL)
{
node->right->parent = node->parent; // step1
node->parent->right = node->right; // step2
}
else
{
node->parent->right = NULL;
}
}
self->_rebalance(self, node->parent);
}
tree_node_free(&node);
return true;
}
static bool tree_avl_delete_double_child(struct _tree* self, struct _tree_node* node)
{
assert(self != NULL);
assert(node != NULL);
struct _tree_node* tmp = tree_find_min(self, node->right);
if (tmp != NULL)
{
memmove(node->obj, tmp->obj, self->_obj_size);
tree_avl_delete_single_child(self, tmp);
}
return true;
}
static bool tree_avl_delete(struct _tree* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
assert(self->compare != NULL);
if (self->empty(self))
{
return false;
}
struct _tree_node* node = tree_find(self, obj);
if (node == NULL)
{
return false;
}
if ((node->left != NULL) && (node->right != NULL))
{
// have two child
tree_avl_delete_double_child(self, node);
}
else
{
// have singule child or no child
tree_avl_delete_single_child(self, node);
}
self->_size--;
return true;
}
static rbt_color tree_color(struct _tree_node* node)
{
assert(node != NULL);
return node->color;
}
static bool tree_set_color(struct _tree_node* node, rbt_color color)
{
assert(node != NULL);
node->color = color;
return true;
}
static struct _tree_node* tree_rb_turn_left(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
struct _tree_node* node = root->right;
if (node == NULL)
{
return root;
}
if (root->parent == NULL)
{
self->_root = node; // step1
}
else
{
if (root->parent->left == root)
{
root->parent->left = node; // step1
}
else if (root->parent->right == root)
{
root->parent->right = node; // setp1
}
}
node->parent = root->parent; // step2
root->parent = node; // step3
root->right = node->left; // step4
if (node->left != NULL)
{
node->left->parent = root; // step5
}
node->left = root; // step6
return node;
}
static struct _tree_node* tree_rb_turn_right(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
struct _tree_node* node = root->left;
if (node == NULL)
{
return root;
}
if (root->parent == NULL)
{
self->_root = node; // step1
}
else
{
if (root->parent->left == root)
{
root->parent->left = node; // step1
}
else if (root->parent->right == root)
{
root->parent->right = node; // setp1
}
}
node->parent = root->parent; // step2
root->parent = node; // step3
root->left = node->right; // step4
if (node->right != NULL)
{
node->right->parent = root; // step5
}
node->right = root; // step6
return node;
}
static bool tree_rb_insert(struct _tree* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
assert(self->compare != NULL);
struct _tree_node* new_node = NULL;
if (self->_root == NULL)
{
// if tree is empty
new_node = tree_node_new(self, obj);
if (new_node == NULL)
{
return false;
}
self->_root = new_node;
}
else
{
struct _tree_node* root = tree_find_pos(self, obj);
if (self->compare(obj, root->obj) == 0)
{
// if obj is exist in tree, return false
return false;
}
new_node = tree_node_new(self, obj);
if (new_node == NULL)
{
return false;
}
if (self->compare(obj, root->obj) < 0)
{
root->left = new_node;
new_node->parent = root;
}
else /*if (self->compare(obj, root->obj) > 0)*/
{
root->right = new_node;
new_node->parent = root;
}
}
self->_rebalance(self, new_node);
self->_size++;
return true;
}
/**
* @brief
*
* 以 balance = rigth - left 为标准,调整平衡因子
*
* | 情况 | root->balance | node->balance | 调整方式 |
* | ---- | ------------ | -------------- | -------- |
* | 1 | 2 | >= 0 | 左旋
* | 2 | 2 | < 0 | 先右旋后左旋
* | 3 | -2 | <= 0 | 右旋
* | 4 | -2 | > 0 | 先左旋后右旋
*
* @param self
* @return true
* @return false
*/
static bool tree_rb_rebalance(struct _tree* self, struct _tree_node* node)
{
assert(self != NULL);
if (node == NULL)
{
return false;
}
struct _tree_node* father = NULL;
struct _tree_node* grandfather = NULL;
struct _tree_node* uncle = NULL;
/**
* @brief 新插入节点为红色,且父节点为红色的情况下,需要调整。
*
* 主要考虑前三种情况[1-3],其余三种[4-6]对称操作即可
*
* 原则只有一个,那就是想办法维持红黑树性质不变
*
* | 情况 | 说明 | 调整方式 |
* | ---- | --- | -------- |
* | 0 | 父节点为黑色 | 不用处理
* | 1 | 父红,爷黑,叔红 | 仅变色即可:父黑,爷红,叔黑
* | 2 | 父红,爷黑,叔黑 | (若爷孙在同一边)父黑,爷红,爷左/右旋
* | 3 | 父红,爷黑,叔黑 | (若爷孙在不同边)先父左右旋,将新父变黑,随后爷红,爷左/右旋
*/
while (node->parent != NULL && node->parent->color == RBT_RED)
{
father = node->parent;
grandfather = father->parent;
if (father == grandfather->left)
{
uncle = grandfather->right;
if (uncle != NULL && uncle->color == RBT_RED) // uncle is red
{
father->color = RBT_BLACK;
uncle->color = RBT_BLACK;
grandfather->color = RBT_RED;
node = grandfather;
}
else // uncle is black
{
if (node == father->right)
{
node = tree_rb_turn_left(self, father);
node->color = RBT_BLACK;
}
else
{
father->color = RBT_BLACK;
}
grandfather->color = RBT_RED;
node = tree_rb_turn_right(self, grandfather);
break;
}
}
else
{
uncle = grandfather->left;
if (uncle != NULL && uncle->color == RBT_RED) // uncle is red
{
father->color = RBT_BLACK;
uncle->color = RBT_BLACK;
grandfather->color = RBT_RED;
node = grandfather;
}
else // uncle is black
{
if (node == father->left)
{
node = tree_rb_turn_right(self, father);
node->color = RBT_BLACK;
}
else
{
father->color = RBT_BLACK;
}
grandfather->color = RBT_RED;
node = tree_rb_turn_left(self, grandfather);
break;
}
}
}
if (node->parent == NULL)
{
self->_root = node;
node->color = RBT_BLACK;
}
return true;
}
static bool tree_rb_delete_fix(struct _tree* self, struct _tree_node* node)
{
assert(self != NULL);
struct _tree_node* father = NULL;
struct _tree_node* brother = NULL;
struct _tree_node* tmp = NULL;
if (node == NULL)
{
return false;
}
// the color of node is black
while (node->parent != NULL && node->color == RBT_BLACK)
{
father = node->parent;
if (father->left == node)
{
brother = father->right;
if (brother->color == RBT_RED)
{
// case 1
// father is black, brother is red
// brother has two black children
// so ...
brother->color = RBT_BLACK;
father->color = RBT_RED;
tmp = tree_rb_turn_left(self, father);
// After deleting the node, it became unbalanced
// so convert to case5
}
else if (brother->right != NULL && brother->right->color == RBT_RED)
{
// case 2
brother->color = father->color;
father->color = RBT_BLACK;
brother->right->color = RBT_BLACK;
node = tree_rb_turn_left(self, father);
// After deleting the node, it remains balanced
break;
}
else if (brother->left != NULL && brother->left->color == RBT_RED)
{
// case 3
brother->color = RBT_RED;
brother->left->color = RBT_BLACK;
tmp = tree_rb_turn_right(self, brother);
// Convert to case2
}
else
{
if (father->color == RBT_BLACK)
{
// case 4
// father is black, brother has no children
brother->color = RBT_RED;
node = father;
// After deleting the node, it became unbalanced
}
else
{
// case 5
// father is red, brother has no children
// if delete the node, it remains balanced
brother->color = RBT_RED;
father->color = RBT_BLACK;
break;
}
}
}
else
{
// symmetric
brother = father->left;
if (brother->color == RBT_RED)
{
// case1
brother->color = RBT_BLACK;
father->color = RBT_RED;
tmp = tree_rb_turn_right(self, father);
}
else if (brother->left != NULL && brother->left->color == RBT_RED)
{
// case2
brother->color = father->color;
father->color = RBT_BLACK;
brother->left->color = RBT_BLACK;
node = tree_rb_turn_right(self, father);
break;
}
else if (brother->right != NULL && brother->right->color == RBT_RED)
{
// case3
brother->color = RBT_RED;
brother->right->color = RBT_BLACK;
tmp = tree_rb_turn_left(self, brother);
// convert to case2
}
else
{
if (father->color == RBT_BLACK)
{
// case4
brother->color = RBT_RED;
node = father;
}
else
{
// case5
brother->color = RBT_RED;
father->color = RBT_BLACK;
break;
}
}
}
if (tmp != NULL && tmp->parent == NULL)
{
self->_root = tmp;
}
}
if (node->parent == NULL)
{
self->_root = node;
}
self->_root->color = RBT_BLACK;
return true;
}
static bool tree_rb_delete(struct _tree* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
assert(self->compare != NULL);
if (self->empty(self))
{
return false;
}
struct _tree_node* node = tree_find(self, obj);
if (node == NULL)
{
return false;
}
struct _tree_node* tmp = NULL;
if (node->left == NULL && node->right == NULL)
{
tmp = node;
}
else if (node->left != NULL && node->right == NULL)
{
// node->left must be red
tmp = node->left;
memmove(node->obj, tmp->obj, self->_obj_size);
}
else if (node->left == NULL && node->right != NULL)
{
// node->right must be red
tmp = node->right;
memmove(node->obj, tmp->obj, self->_obj_size);
}
else
{
// 1. find the min node in right subtree
// 2. replace the node with min node
// 3. delete the min node
tmp = tree_find_min(self, node->right);
memmove(node->obj, tmp->obj, self->_obj_size);
if (tmp->right != NULL)
{
// tmp->right must be red
memmove(tmp->obj, tmp->right->obj, self->_obj_size);
tmp = tmp->right;
}
}
if (tmp->color == RBT_BLACK)
{
tree_rb_delete_fix(self, tmp);
}
if (tmp->parent != NULL)
{
if (tmp->parent->left == tmp)
{
tmp->parent->left = NULL;
}
else
{
tmp->parent->right = NULL;
}
}
else
{
self->_root = NULL;
}
tree_node_free(&tmp);
self->_size--;
return true;
}
static bool tree_empty(struct _tree* self)
{
assert(self != NULL);
return !self->size(self);
}
static uint32_t tree_size(struct _tree* self)
{
assert(self != NULL);
return self->_size;
}
static bool tree_clear(struct _tree* self)
{
assert(self != NULL);
if (self->_root == NULL)
{
// return false;
return true;
}
struct _tree_node* node = self->_root;
queue_t queue = queue_new(sizeof(struct _tree_node*));
queue->push(queue, &node);
while (!queue->empty(queue))
{
queue->pop(queue, &node);
if (node->left != NULL)
{
queue->push(queue, &node->left);
}
if (node->right != NULL)
{
queue->push(queue, &node->right);
}
tree_node_free(&node);
}
queue_free(&queue);
self->_root = NULL;
self->_size = 0;
return true;
}
static void tree_destory(struct _tree* self)
{
assert(self != NULL);
self->clear(self);
self->_root = NULL;
if (self->stack != NULL)
{
stack_free(&self->stack);
}
if (self->queue != NULL)
{
queue_free(&self->queue);
}
}
static uint32_t tree_height(struct _tree* self)
{
return tree_height_node(self, self->_root);
}
static bool tree_min(struct _tree* self, void* obj)
{
assert(self != NULL);
struct _tree_node* node = tree_find_min(self, self->_root);
if (node == NULL)
{
return false;
}
memmove(obj, node->obj, self->_obj_size);
return true;
}
static bool tree_max(struct _tree* self, void* obj)
{
assert(self != NULL);
struct _tree_node* node = tree_find_max(self, self->_root);
if (node == NULL)
{
return false;
}
memmove(obj, node->obj, self->_obj_size);
return true;
}
static bool tree_iter_hasnext(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->_container != NULL);
tree_t self = (tree_t)iter->_container;
if(iter->_index < self->size(self))
{
return true;
}
return false;
}
static const void* tree_iter_next(struct _iterator* iter)
{
assert(iter != NULL);
assert(iter->_container != NULL);
tree_t self = (tree_t)iter->_container;
void *obj = NULL;
struct _tree_node* cur_node = iter->_node;
struct _tree_node* target_node = NULL;
switch (iter->_order)
{
case TREE_DFS_PRE:
case TREE_DFS_PRE_R:
{
struct _tree_node* node = NULL;
if (iter->_order == TREE_DFS_PRE)
{
while (!self->stack->empty(self->stack) || cur_node != NULL)
{
if (cur_node != NULL)
{
target_node = cur_node;
self->stack->push(self->stack, &cur_node);
cur_node = cur_node->left;
break;
}
else
{
self->stack->pop(self->stack, &cur_node);
cur_node = cur_node->right;
}
}
}
else
{
while (!self->stack->empty(self->stack) || cur_node != NULL)
{
if (cur_node != NULL)
{
target_node = cur_node;
self->stack->push(self->stack, &cur_node);
cur_node = cur_node->right;
break;
}
else
{
self->stack->pop(self->stack, &cur_node);
cur_node = cur_node->left;
}
}
}
}break;
case TREE_DFS_IN:
case TREE_DFS_IN_R:
{
if (iter->_order == TREE_DFS_IN)
{
while (!self->stack->empty(self->stack) || cur_node != NULL)
{
if (cur_node != NULL)
{
self->stack->push(self->stack, &cur_node);
cur_node = cur_node->left;
}
else
{
self->stack->pop(self->stack, &cur_node);
target_node = cur_node;
cur_node = cur_node->right;
break;
}
}
}
else
{
while (!self->stack->empty(self->stack) || cur_node != NULL)
{
if (cur_node != NULL)
{
self->stack->push(self->stack, &cur_node);
cur_node = cur_node->right;
}
else
{
self->stack->pop(self->stack, &cur_node);
target_node = cur_node;
cur_node = cur_node->left;
break;
}
}
}
}break;
case TREE_DFS_POST:
case TREE_DFS_POST_R:
{
if (!self->stack->empty(self->stack))
{
self->stack->pop(self->stack, &cur_node);
target_node = cur_node;
}
}break;
case TREE_BFS:
case TREE_BFS_R:
{
queue_t queue = self->queue;
if (!queue->empty(queue) && cur_node != NULL)
{
queue->pop(queue, &cur_node);
target_node = cur_node;
if (iter->_order == TREE_BFS)
{
if (cur_node->left != NULL)
{
queue->push(queue, &cur_node->left);
}
if (cur_node->right != NULL)
{
queue->push(queue, &cur_node->right);
}
}
else
{
if (cur_node->right != NULL)
{
queue->push(queue, &cur_node->right);
}
if (cur_node->left != NULL)
{
queue->push(queue, &cur_node->left);
}
}
}
}break;
default:
{
}break;
}
iter->_node = cur_node;
obj = target_node->obj;
iter->_index += 1;
return obj;
}
static iterator_t tree_iter(struct _tree* self, enum _tree_order order)
{
assert(self != NULL);
iterator_t iter = &self->_iter;
iter->_container = self;
iter->_index = 0;
iter->_node = self->_root;
iter->_order = order;
iter->hasnext = tree_iter_hasnext;
iter->next = tree_iter_next;
self->stack->clear(self->stack);
self->queue->clear(self->queue);
switch (iter->_order)
{
case TREE_DFS_PRE:
case TREE_DFS_PRE_R:
{
// pass
}break;
case TREE_DFS_IN:
case TREE_DFS_IN_R:
{
// pass
}break;
case TREE_DFS_POST:
case TREE_DFS_POST_R:
{
struct _tree_node* node = self->_root;
self->stack->clear(self->stack);
stack_t stack = stack_new(sizeof(struct _tree_node*));
if (iter->_order == TREE_DFS_POST)
{
while (!stack->empty(stack) || node != NULL)
{
if (node != NULL)
{
self->stack->push(self->stack, &node);
stack->push(stack, &node);
node = node->right;
}
else
{
stack->pop(stack, &node);
node = node->left;
}
}
}
else
{
while (!stack->empty(stack) || node != NULL)
{
if (node != NULL)
{
self->stack->push(self->stack, &node);
stack->push(stack, &node);
node = node->left;
}
else
{
stack->pop(stack, &node);
node = node->right;
}
}
}
stack_free(&stack);
}break;
case TREE_BFS:
case TREE_BFS_R:
{
// pass
self->queue->push(self->queue, &self->_root);
}break;
default:
{
}break;
}
return iter;
}
static bool tree_avl_init(struct _tree* self, uint32_t obj_size)
{
assert(self != NULL);
// -------------------- private --------------------
self->_obj_size = obj_size;
self->_size = 0;
// self->_capacity = 64;
// self->_ratio = 2;
self->_root = NULL;
self->stack = stack_new(sizeof(struct _tree_node*));
if (self->stack == NULL)
{
return false;
}
self->queue = queue_new(sizeof(struct _tree_node*));
if (self->queue == NULL)
{
stack_free(&self->stack);
return false;
}
self->_rebalance = tree_avl_rebalance;
self->_destory = tree_destory;
// -------------------- public --------------------
// kernel
self->insert = tree_avl_insert;
self->delete = tree_avl_delete;
self->height = tree_height;
// base
self->clear = tree_clear;
self->empty = tree_empty;
self->size = tree_size;
// iter
self->iter = tree_iter;
// others
self->max = tree_max;
self->min = tree_min;
// -------------------- default --------------------
self->compare = default_compare;
self->print_obj = default_print_obj;
return true;
}
static bool tree_rb_init(struct _tree* self, uint32_t obj_size)
{
assert(self != NULL);
// -------------------- private --------------------
self->_obj_size = obj_size;
self->_size = 0;
// self->_capacity = 64;
// self->_ratio = 2;
self->_root = NULL;
self->stack = stack_new(sizeof(struct _tree_node*));
if (self->stack == NULL)
{
return false;
}
self->queue = queue_new(sizeof(struct _tree_node*));
if (self->queue == NULL)
{
stack_free(&self->stack);
return false;
}
self->_rebalance = tree_rb_rebalance;
self->_destory = tree_destory;
// -------------------- public --------------------
// kernel
self->insert = tree_rb_insert;
self->delete = tree_rb_delete;
self->height = tree_height;
// base
self->clear = tree_clear;
self->empty = tree_empty;
self->size = tree_size;
// iter
self->iter = tree_iter;
// others
self->max = tree_max;
self->min = tree_min;
// -------------------- default --------------------
self->compare = default_compare;
self->print_obj = default_print_obj;
return true;
}
tree_t tree_avl_new(uint32_t obj_size)
{
tree_t tree = NULL;
tree = (struct _tree*)malloc(sizeof(struct _tree));
if(tree == NULL)
{
return NULL;
}
if(tree_avl_init(tree, obj_size) != true)
{
free(tree);
return NULL;
}
return tree;
}
tree_t tree_rb_new(uint32_t obj_size)
{
tree_t tree = NULL;
tree = (struct _tree*)malloc(sizeof(struct _tree));
if(tree == NULL)
{
return NULL;
}
if(tree_rb_init(tree, obj_size) != true)
{
free(tree);
return NULL;
}
return tree;
}
void tree_free(tree_t* tree)
{
if (*tree != NULL)
{
(*tree)->_destory(*tree);
free(*tree);
}
*tree = NULL;
}