Alright so there is a lot of code here, but I thought it was best in case something wasn't immediately evident in my logic.
My issue starts with the height, and my calculated balancing factor. I have looked up a countless amount of AVL-tree algorithms, and done a lot of rough work on paper to try to figure out the best way to tackle the balancing aspect of this beast of a tree. Here is what I've gotton:
typedef struct node {
char* key;
struct node *left;
struct node *right;
int height;
int frequency;
}node;
int max(int a, int b)
{
if(a > b)
{
return a;
}
else
return b;
}
// A utility function to get height of the tree
int height(node* N)
{
if(N==NULL)
return -1;
return N->height;
}
// A utility function to get maximum of two integers
int avlHeight(node* N) {
if(N == NULL)
return -1;
else
return max(height(N->left), height(N->right))+1;
}
node *rightRotate(node *y) //preform a right AVL rotation
{
node *x = y->left;
node *T2 = x->right;
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left), height(y->right))+1;
x->height = max(height(x->left), height(x->right))+1;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
node *leftRotate(node *x) //perform a left AVL rotation
{
node *y = x->right;
node *T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(height(x->left), height(x->right))+1;
y->height = max(height(y->left), height(y->right))+1;
// Return new root
return y;
}
// Get Balance factor of node N
int getBalance(node *N)//get the balance factor
{
if (N == NULL)
return -1;
return height(N->left) - height(N->right);
}
node* insert(node* node, char* key)//function to insert new nodes to the tree
{
if (node == NULL)
return (newNode(key));
// printf("%s",key);
if(strcmp(node->key, key)==0)
{
node->frequency = node->frequency+1;
return node;
}
if (strcmp(key, node->key) < 0)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
/* 2. Update height of this ancestor node */
node->height = max(height(node->left), height(node->right)) + 1;
/* 3. Get the balance factor of this ancestor node to check whether
this node became unbalanced */
int balance = getBalance(node);
printf("%d\n",balance);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && strcmp(key, node->left->key)<0) {
return rightRotate(node);
}
// Right Right Case
if (balance < -1 && strcmp(key, node->right->key)>0)
return leftRotate(node);
// Left Right Case
if (balance > 1 && strcmp(key, node->left->key)>0) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && strcmp(key, node->right->key)<0) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
/* return the (unchanged) node pointer */
return node;
}
I̶ ̶d̶o̶ ̶n̶o̶t̶ ̶g̶e̶t̶ ̶a̶n̶y̶ ̶s̶e̶g̶-̶f̶a̶u̶l̶t̶s̶,̶ ̶e̶r̶r̶o̶r̶s̶,̶ ̶o̶r̶ ̶w̶a̶r̶n̶i̶n̶g̶s̶.̶ The program segfaults when the balance factor is 2. I am parsing roughly 44k lines of keys into this tree, and any multiples are being added to the structs frequency counter. The only thing that is not correct with my tree is that the frequency is off by 1-3 elements for any given node, and the heights are not what they should be for all elements.
I was pretty sure when I was debugging it had to do with my balancing algorithm, because for one my heights were completely off (got as high as 7 I believe) and about 70% of my nodes had the correct amount of counts (frequency).
My big question: What is wrong with my balancing logic and/or rotation logic? Is my entire code wrong, or am I at least on the right track?
**after updating code for some god forsaken reason when I take out the node I segfault at, the entire program works, but gives me the wrong frequencies still :/
So quite literally 1 element/node makes this segfault, yet it is still wrong...
example input->
wrn69 flr830 flr662 flr830 flr830
flr231 flr2166 flr1854 wrn69 wrn69
flr231 flr2166
wrn69
flr830