117 lines
2.8 KiB
C
117 lines
2.8 KiB
C
|
/*
|
||
|
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 2019-10-12 Jesven first version
|
||
|
* 2022-11-14 WangXiaoyao Optimize for generic use case
|
||
|
* and performance
|
||
|
*/
|
||
|
#ifndef __UTIL_TREE_AVL_H__
|
||
|
#define __UTIL_TREE_AVL_H__
|
||
|
|
||
|
#include <rtdef.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
struct util_avl_struct
|
||
|
{
|
||
|
struct util_avl_struct *avl_left;
|
||
|
struct util_avl_struct *avl_right;
|
||
|
struct util_avl_struct *parent;
|
||
|
size_t height;
|
||
|
};
|
||
|
|
||
|
#define AVL_ROOT ((struct util_avl_struct *)0)
|
||
|
|
||
|
struct util_avl_root
|
||
|
{
|
||
|
struct util_avl_struct *root_node;
|
||
|
};
|
||
|
|
||
|
void util_avl_rebalance(struct util_avl_struct *node,
|
||
|
struct util_avl_root *root);
|
||
|
|
||
|
void util_avl_remove(struct util_avl_struct *node, struct util_avl_root *root);
|
||
|
|
||
|
static inline void util_avl_link(struct util_avl_struct *new_node,
|
||
|
struct util_avl_struct *parent,
|
||
|
struct util_avl_struct **nodeplace)
|
||
|
{
|
||
|
new_node->avl_left = AVL_ROOT;
|
||
|
new_node->avl_right = AVL_ROOT;
|
||
|
new_node->parent = parent;
|
||
|
new_node->height = 1;
|
||
|
*nodeplace = new_node;
|
||
|
}
|
||
|
|
||
|
static inline struct util_avl_struct *util_avl_next(
|
||
|
struct util_avl_struct *node)
|
||
|
{
|
||
|
struct util_avl_struct *successor = 0;
|
||
|
if (node)
|
||
|
{
|
||
|
if (node->avl_right)
|
||
|
{
|
||
|
node = node->avl_right;
|
||
|
while (node->avl_left)
|
||
|
node = node->avl_left;
|
||
|
successor = node;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
while ((successor = node->parent) && (node == successor->avl_right))
|
||
|
node = successor;
|
||
|
}
|
||
|
}
|
||
|
return successor;
|
||
|
}
|
||
|
|
||
|
static inline struct util_avl_struct *util_avl_prev(
|
||
|
struct util_avl_struct *node)
|
||
|
{
|
||
|
struct util_avl_struct *predecessor = 0;
|
||
|
if (node)
|
||
|
{
|
||
|
if (node->avl_left)
|
||
|
{
|
||
|
node = node->avl_left;
|
||
|
while (node->avl_right)
|
||
|
node = node->avl_right;
|
||
|
predecessor = node;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
while ((predecessor = node->parent) &&
|
||
|
(node == predecessor->avl_left))
|
||
|
node = predecessor;
|
||
|
}
|
||
|
}
|
||
|
return predecessor;
|
||
|
}
|
||
|
|
||
|
static inline struct util_avl_struct *util_avl_first(struct util_avl_root *root)
|
||
|
{
|
||
|
struct util_avl_struct *first = root->root_node;
|
||
|
if (first)
|
||
|
{
|
||
|
while (first->avl_left)
|
||
|
first = first->avl_left;
|
||
|
}
|
||
|
return first;
|
||
|
}
|
||
|
|
||
|
static inline struct util_avl_struct *util_avl_last(struct util_avl_root *root)
|
||
|
{
|
||
|
struct util_avl_struct *last = root->root_node;
|
||
|
if (last)
|
||
|
{
|
||
|
while (last->avl_right)
|
||
|
last = last->avl_right;
|
||
|
}
|
||
|
return last;
|
||
|
}
|
||
|
|
||
|
#endif /* __UTIL_TREE_AVL_H__ */
|