I am currently trying to construct a AVL tree in c where each node contains a name and a value. The tree should be sorted by value. Currently, with the input:
6 Franklin
4 David
1 Anna
2 Bob
3 Cora
5 Ella
7 Griffin
the tree ends up looking like
David
/ \
Anna Franklin
\ / \
Bob Ella Griffin
\
Cora
when it should look like
David
/ \
Bob Franklin
/ \ / \
Anna Cora Ella Griffin
this seems to be the threshold size for it breaking, with input consisting of less nodes working. relevant code:
#define MAX(X, Y) ((X) < (Y) ? (Y) : (X))
int height(struct Tree_Node *n) {
if (n->right && n->left) return MAX(n->right->height, n->left->height) + 1;
if (n->left && !n->right) return n->left->height + 1;
if (n->right && !n->left) return n->right->height + 1;
return 0;
}
int balance(struct Tree_Node *n) {
if (n->left && n->right) return n->left->height - n->right->height;
if (n->left && !n->right) return n->left->height;
if (!n->left && n->right) return n->right->height;
return 0;
}
struct Tree_Node *rotate_left(struct Tree_Node *n){
struct Tree_Node *p;
struct Tree_Node *tp;
p = n;
tp = p->left;
p->left = tp->right;
tp->right = p;
return tp;
}
struct Tree_Node *rotate_right(struct Tree_Node *n){
struct Tree_Node *p;
struct Tree_Node *tp;
p = n;
tp = p->right;
p->right = tp->left;
tp->left = p;
return tp;
}
struct Tree_Node *rotate_right_left(struct Tree_Node *n) {
struct Tree_Node *p;
struct Tree_Node *tp;
struct Tree_Node *tp2;
p = n;
tp = p->right;
tp2 =p->right->left;
p -> right = tp2->left;
tp ->left = tp2->right;
tp2 ->left = p;
tp2->right = tp;
return tp2;
}
struct Tree_Node *rotate_left_right(struct Tree_Node *n) {
struct Tree_Node *p;
struct Tree_Node *tp;
struct Tree_Node *tp2;
p = n;
tp = p->left;
tp2 =p->left->right;
p -> left = tp2->right;
tp ->right = tp2->left;
tp2 ->right = p;
tp2->left = tp;
return tp2;
}
struct Tree_Node *insert_leaf(struct Tree_Node *root, struct Tree_Node *new) {
if (!root) {
root = new;
root->left = NULL;
root->right = NULL;
root->height = 0;
return root;
}
else {
if (new->value < root->value) root->left = insert_leaf(root->left, new);
else root->right = insert_leaf(root->right, new);
}
root->height = height(root);
if (balance(root) > 1 && new->value < root->left->value) root = rotate_left(root);
else if (balance(root) < -1 && new->value > root->right->value) root = rotate_right(root);
else if (balance(root) < -1 && new->value < root->right->value) root = rotate_right_left(root);
else if (balance(root) > 1 && new->value > root->left->value) root = rotate_left_right(root);
return root;
}
There are the following issues:
The height of a leaf node is 1, not 0. So the last return
in the height
function should be:
return 1;
And in the insert_leaf
function, remove these two lines from the if
block:
root->height = 0; return root;
That way the execution will continue with a call to height
to set this value correctly to 1.
The rotation functions will change the height of node(s) that are descendant(s) of the returned node, so you must update their height(s). In the single rotation functions, add therefore this line:
p->height = height(p);
And in the double rotation functions, add:
p->height = height(p); tp->height = height(tp);
You define the balance for a right-heavy tree as negative with n->left->height - n->right->height
, but then make it positive when n->left
is NULL
and n->right
is not. It should be negative in that case. So add the negation operator like this:
if (;n->left && n->right) return -n->right->height;
With these changes the expected tree will be built for your test case.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.