我正在学习AVL树,这对我来说很有意思,但我无法让它正常工作。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LEFT -1
#define BAL 0
#define RIGHT 1
typedef int Key;
typedef void * Info;
struct avltree {
int bal;
Key key;
Info info;
struct avltree *left, *right;
};
typedef struct avltree *BTree;
BTree newBTree (Key k, Info i, BTree l, BTree r) {
BTree n;
n = (BTree) malloc (sizeof (struct avltree));
if (n) {
n->key = k;
n->info = i;
n->bal = BAL;
n->left = l;
n->right = r;
}
return n;
}
BTree fixLeft (BTree a);
BTree fixRight (BTree a);
BTree addAux (BTree a, Key k, Info i);
BTree rotateLeft (BTree a) {
BTree b = a->right;
a->right = b->left;
b->left = a;
return b;
}
BTree rotateRight (BTree a) {
BTree b = a->left;
a->left = b->right;
b->right = a;
return b;
}
BTree add (BTree a, Key k, Info i) {
return (addAux (a,k,i));
}
int max (int x, int y){
int m = x>y ? x : y;
return m;
}
int height(BTree t){
if(!t){
return 0;
}
int m = max(height(t->left), height(t->right)) + 1;
return m;
}
BTree addAux (BTree a, Key k, Info i) {
if (a == NULL) {
a = newBTree (k,i,NULL,NULL);
a->bal = BAL;
} else if (a->key > k) {
a->left = addAux (a->left,k,i);
//once a->left gets his value, bellow i will compare
//the size of both left and right subtrees
int l = height(a->left);
int r = height(a->right);
//If the left one is bigger by just one unit , is ok
//as it gets a mark saying the left side is heavier
//and otherwise if it's bigger on the right
if(l-r == 1){
a->bal = LEFT;
}else if(l-r == -1){
a->bal = RIGHT;
}
//Here i tell that if the left side has a heavy-factor of 2
//i get it fixed by calling fixLeft
else if(l-r > 1){
a->bal = LEFT;
fixLeft(a);
}else if(l-r < -1){
a->bal = RIGHT;
fixRight(a);
}
//And vice-versa on this else
} else { // (a->key < k)
a->right = addAux (a->right,k,i);
int l = height(a->left);
int r = height(a->right);
if(l-r == 1){
a->bal = LEFT;
}else if(l-r == -1){
a->bal = RIGHT;
}
else if(l-r > 1){
a->bal = LEFT;
fixLeft(a);
}else if(l-r < -1){
a->bal = RIGHT;
fixRight(a);
}
}
return a;
}
BTree fixLeft (BTree a) {
if (a->left->bal == LEFT) {
a = rotateRight (a);
a->bal = a->right->bal = BAL;
}
else {
a->left = rotateLeft(a->left);
a = rotateRight (a);
a->bal = a->right->bal = BAL;
}
return a;
}
BTree fixRight (BTree a) {
if (a->right->bal == RIGHT) {
a = rotateLeft (a);
a->bal = a->left->bal = BAL;
}
else {
a->right = rotateRight(a->right);
a = rotateLeft (a);
a->bal = a->left->bal = a->right->bal = BAL;
}
return a;
}
void dumpKeys (BTree a, int level){
int l;
if (a) {
dumpKeys (a->right, level+1);
for (l=0;l<level;l++) printf ("%5c",' ');
printf ("%5d\n", a->key);
dumpKeys (a->left, level+1);
}
}
int main(){
BTree a = NULL;
a=add(a,10,NULL);
a=add(a,20,NULL);
a=add(a,15,NULL);
dumpKeys (a,0);
return 0;
}
在某些地方我失去了指向下一个节点的指针我猜,它只输出根或插入的第一个元素。调试器没有错误。
谢谢!
最小,完整且可验证的示例:
答案 0 :(得分:0)
这个问题很容易解决,几个小时后我真的很轻松。
我在返回BTree时调用函数fixRight和fixLeft,但是没有将返回值赋值为空。
所以,这是错误并修复:
...
else if(l-r > 1){
a->bal = LEFT;
a = fixLeft(a); //HERE
}else if(l-r < -1){
a->bal = RIGHT;
a = fixRight(a); //HERE
}
...