forked from vieter-v/libvieter
fix(tree): fix wrong rotation function
parent
17c2e15385
commit
70217bee21
|
@ -21,8 +21,12 @@ bool vieter_tree_node_validate(vieter_tree_node *node,
|
||||||
vieter_tree_node_get(node->children[0], vieter_tree_node_black)) &&
|
vieter_tree_node_get(node->children[0], vieter_tree_node_black)) &&
|
||||||
(node->children[1] == NULL ||
|
(node->children[1] == NULL ||
|
||||||
vieter_tree_node_get(node->children[1], vieter_tree_node_black)));
|
vieter_tree_node_get(node->children[1], vieter_tree_node_black)));
|
||||||
|
bool right_child_flag_set =
|
||||||
|
node->parent == NULL ||
|
||||||
|
(vieter_tree_node_get(node, vieter_tree_node_right) ==
|
||||||
|
(node->parent->children[1] == node));
|
||||||
|
|
||||||
return correctly_colored_children &&
|
return correctly_colored_children && right_child_flag_set &&
|
||||||
vieter_tree_node_validate(node->children[0], passed_black_nodes,
|
vieter_tree_node_validate(node->children[0], passed_black_nodes,
|
||||||
expected_black_nodes) &&
|
expected_black_nodes) &&
|
||||||
vieter_tree_node_validate(node->children[1], passed_black_nodes,
|
vieter_tree_node_validate(node->children[1], passed_black_nodes,
|
||||||
|
@ -128,6 +132,14 @@ vieter_tree_node *vieter_tree_node_rotate(vieter_tree_node *old_root,
|
||||||
bool dir) {
|
bool dir) {
|
||||||
vieter_tree_node *new_root = old_root->children[1 - dir];
|
vieter_tree_node *new_root = old_root->children[1 - dir];
|
||||||
|
|
||||||
|
if (old_root->parent != NULL) {
|
||||||
|
vieter_tree_node_set_child(
|
||||||
|
old_root->parent, new_root,
|
||||||
|
vieter_tree_node_get(old_root, vieter_tree_node_right));
|
||||||
|
} else {
|
||||||
|
new_root->parent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Right rotation
|
// Right rotation
|
||||||
if (dir) {
|
if (dir) {
|
||||||
vieter_tree_node_set_child(old_root, new_root->children[1], false);
|
vieter_tree_node_set_child(old_root, new_root->children[1], false);
|
||||||
|
|
|
@ -17,4 +17,5 @@ void vieter_tree_node_balance_after_insert(vieter_tree_node *node);
|
||||||
*/
|
*/
|
||||||
void vieter_tree_node_remove_balanced(vieter_tree_node *node);
|
void vieter_tree_node_remove_balanced(vieter_tree_node *node);
|
||||||
|
|
||||||
|
vieter_tree_node *vieter_tree_node_rotate(vieter_tree_node *old_root, bool dir);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "acutest.h"
|
||||||
|
#include "vieter_tree_internal.h"
|
||||||
|
#include "vieter_tree_node.h"
|
||||||
|
#include "vieter_tree_balancing.h"
|
||||||
|
|
||||||
|
void test_rotate_right() {
|
||||||
|
vieter_tree_node *a = vieter_tree_node_init();
|
||||||
|
vieter_tree_node *b = vieter_tree_node_init();
|
||||||
|
vieter_tree_node *p = vieter_tree_node_init();
|
||||||
|
|
||||||
|
vieter_tree_node_set_child(p, a, false);
|
||||||
|
vieter_tree_node_set_child(p, b, true);
|
||||||
|
|
||||||
|
vieter_tree_node *c = vieter_tree_node_init();
|
||||||
|
vieter_tree_node *q = vieter_tree_node_init();
|
||||||
|
|
||||||
|
vieter_tree_node_set_child(q, p, false);
|
||||||
|
vieter_tree_node_set_child(q, c, true);
|
||||||
|
|
||||||
|
vieter_tree_node *new_root = vieter_tree_node_rotate(q, true);
|
||||||
|
|
||||||
|
TEST_CHECK(new_root == p);
|
||||||
|
TEST_CHECK(new_root->children[0] == a);
|
||||||
|
TEST_CHECK(new_root->children[1] == q);
|
||||||
|
TEST_CHECK(new_root->children[1]->children[0] == b);
|
||||||
|
TEST_CHECK(new_root->children[1]->children[1] == c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_rotate_left() {
|
||||||
|
vieter_tree_node *b = vieter_tree_node_init();
|
||||||
|
vieter_tree_node *c = vieter_tree_node_init();
|
||||||
|
vieter_tree_node *q = vieter_tree_node_init();
|
||||||
|
|
||||||
|
vieter_tree_node_set_child(q, b, false);
|
||||||
|
vieter_tree_node_set_child(q, c, true);
|
||||||
|
|
||||||
|
vieter_tree_node *a = vieter_tree_node_init();
|
||||||
|
vieter_tree_node *p = vieter_tree_node_init();
|
||||||
|
|
||||||
|
vieter_tree_node_set_child(p, a, false);
|
||||||
|
vieter_tree_node_set_child(p, q, true);
|
||||||
|
|
||||||
|
vieter_tree_node *new_root = vieter_tree_node_rotate(p, false);
|
||||||
|
|
||||||
|
TEST_CHECK(new_root == q);
|
||||||
|
TEST_CHECK(new_root->children[0] == p);
|
||||||
|
TEST_CHECK(new_root->children[1] == c);
|
||||||
|
TEST_CHECK(new_root->children[0]->children[0] == a);
|
||||||
|
TEST_CHECK(new_root->children[0]->children[1] == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_LIST = {
|
||||||
|
{"tree tree rotate right", test_rotate_right},
|
||||||
|
{"tree tree rotate left", test_rotate_left},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
|
@ -42,7 +42,7 @@ void test_remove() {
|
||||||
|
|
||||||
void *out;
|
void *out;
|
||||||
|
|
||||||
for (uint64_t i = 0; i < 25; i++) {
|
for (uint64_t i = 0; i < 100; i++) {
|
||||||
TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_ok);
|
TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_ok);
|
||||||
TEST_CHECK(vieter_tree_remove(&out, tree, i) == vieter_tree_ok);
|
TEST_CHECK(vieter_tree_remove(&out, tree, i) == vieter_tree_ok);
|
||||||
TEST_CHECK(vieter_tree_validate(tree));
|
TEST_CHECK(vieter_tree_validate(tree));
|
||||||
|
|
Loading…
Reference in New Issue