我试图实现一个数组到BST,打印出BST(前序)后,我平衡它(AVL树与前序输出)。
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *left;
struct node *right;
int height;
};
struct node *new_node(int data) {
struct node *nn = (struct node *)malloc(sizeof(struct node));
nn->data = data;
nn->left = NULL;
nn->right = NULL;
nn->height = 1;
return nn;
}
struct node *insert(struct node *root, int data) {
if (root == NULL)
return new_node(data);
else {
if (data < root->data)
root->left = insert(root->left, data);
if (data > root->data)
root->right = insert(root->right, data);
return root;
}
}
void pre_order(struct node *root) {
if (root != NULL) {
printf("%d ", root->data);
pre_order(root->left);
pre_order(root->right);
}
}
int height(struct node *n) {
if (n == NULL)
return 0;
return n->height;
}
int max(int a, int b)
{
return (a > b) ? a : b;
}
struct node *rightRotate(struct node *y)
{
struct node *x = y->left;
struct node *T2 = x->right;
x->right = y;
y->left = T2;
y->height = max(height(y->left), height(y->right)) + 1;
x->height = max(height(x->left), height(x->right)) + 1;
return x;
}
struct node *leftRotate(struct node *x) {
struct node *y = x->right;
struct node *T2 = y->left;
y->left = x;
x->right = T2;
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;
return y;
}
int getBalance(struct node *n) {
if (n == NULL)
return 0;
return height(n->left) - height(n->right);
}
struct node *AVLbalance(struct node *root, int data)
{
root->height = 1 + max(height(root->left),
height(root->right));
int balance = getBalance(root);
// Left Left Case
if (balance > 1 && data < root->left->data)
return rightRotate(root);
// Right Right Case
if (balance < -1 && data > root->right->data)
return leftRotate(root);
// Left Right Case
if (balance > 1 && data > root->left->data)
{
root->left = leftRotate(root->left);
return rightRotate(root);
}
// Right Left Case
if (balance < -1 && data < root->right->data)
{
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
int main() {
struct node *root = NULL;
int arr[] = { 5, 7, 2, 4, 6 };
int n = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < n; i++)
root = insert(root, arr[i]);
printf("BST Pre-order:\n");
pre_order(root);
for (int j = 0; j < n; j++)
root = AVLbalance(root, arr[j]);
printf("\nBalanced (AVL) Pre-order:\n");
pre_order(root);
return 0;
}
字符串
在尝试了几个小时后,我不知道树在被调用时是否在平衡自己。是否有逻辑错误?程序编译时没有任何警告或错误。帮助!
2条答案
按热度按时间inn6fuwd1#
主要的问题是,您依赖
nn->height
来平衡树,但在插入新节点时没有更新节点高度。你可以这样修改插入函数:
字符串
但这还不够:函数
AVLbalance
仅处理树的根节点,因此在插入所有值之后重新平衡树不起作用。当检测到不平衡时,应该在
insert
函数中重新平衡子树,即当在子树中插入data
时,增加子树的高度超过另一个子树的长度+1.保持每个节点的高度是多余的。每个子树的一个比特表示它已经高于它的兄弟应该足以检测insert
中重新平衡的需要。让树一直保持平衡下面是
insert
函数的简单实现,它在插入时重新平衡树:型
mutmk8jj2#
你过度解读了自我平衡。
这并不意味着保持平衡而不将其编码在树例程中。
在每个节点中保留可能有助于保持/恢复平衡的信息是不够的:
在每次修改操作结束时需要保证平衡
(插入、删除、合并/合并、拆分.)。