Function to balance a search tree - c

So I need some help on this since I'm reading from a file and inserting into a list and a tree for search purposes, this function is not saving all the nodes, it loses the information while running.
fe=left child
fd=right child
NodeCount returns how many nodes are in the Tree and the rotate functions are working properly
TREE *rotate left(TREE *A) //right just replace fe for fd:
{
ARVORE *aux;
aux=A->fd;
A->fd=aux->fe;
aux->fe=A;
return A;
}
the balance function returns 1 if the tree is balanced and 0 if not
TREE *balances (TREE *A)
{
TREE *aux = A;
if(aux == NULL)
return A;
while(!balance(aux))
{
if((NodeCount(aux->fe) - NodeCount(aux->fd)) > 1)
aux=rotateright(aux);
if((NodeCount(aux->fd) - NodeCount(aux->fe)) > 1)
aux=rotateleft(aux);
return aux;
}
return A;
}
output :
before balances :0
01gwztbs0d#yahoo.com
2v7t5k72fb#clix.pt
2v7t5k72fb#clix.pt
3ahf#sapo.pt
bysws#clix.pt
cop8m5#clix.pt lost
ibnor#yahoo.com lost
lglkge#clix.pt lost
sck0z#yahoo.com lost
After Balances
01gwztbs0d#yahoo.com
2v7t5k72fb#clix.pt
2v7t5k72fb#clix.pt
3ahf#sapo.pt
bysws#clix.pt
Equi:1

Your problem is logical. Your if-statements are not logically connected with each other and the conditions overlap. As a result aux is overwritten with all the statements of the second if and then returned as such.
Example: first aux = cop8m5#clix.pt; then aux = 01gwztbs0d#yahoo.com; and 01gwztbs0d#yahoo.com is returned.
If you look closely, you would see that what is missing, is exactly the right partial subtree (all elements greater than the root). As it looks it is an inorder traversal, so therefore the root must be bysws#clix.pt. From here you can easily see it yourself.
The quickest solution is to put one return aux; in the body of each if-statement:
while(!balance(aux)) {
if ((NodeCount(aux->fe) - NodeCount(aux->fd)) > 1) {
aux=rotateright(aux);
return aux;
}
if ((NodeCount(aux->fd) - NodeCount(aux->fe)) > 1) {
aux=rotateleft(aux);
return aux;
}
}

Related

How can i generate a binary code table of a huffman tree?

I want to implement an function which gives me a binary code for each char in a huffman tree.
To implement the function i tried traversing the table by using a recursive function. However i don't know how to fill the result the binary code for each char so that the function returns an array of struct with all the chars and binary codes
I hope someone can point me in the right direction.
Thanks ahead!
Ok, let's see a possible solution:
#include <stdint.h>
typedef struct code {
size_t code_length;
uint32_t code;
} code;
void compute_code_table(tree_t node, code *t, code c)
{
if (node->left == NULL)
t[node->letter] = c;
else {
c.code_length++;
c.code <<= 1;
compute_code_table(node->left, t, c);
c.code += 1;
compute_code_table(node->right, t, c);
}
}
void code_print(code *c)
{
size_t n = c->code_length;
while (n --> 0)
putchar('0' + ((c->code >> n) & 1));
}
int main(void)
{
tree_t root = fixed_tree();
code table[256] = { 0 };
code c = { 0 };
compute_code_table(root, table, c);
for (size_t i = 0; i < 256; ++i) {
if (table[i].code_length) {
printf("%c\t", i);
code_print(table + i);
printf("\n");
}
}
}
Basically the idea is to have a table which is filled at every leaf. While doing the recursion we pass the current node, the table and the current code. If we are at a leaf we just store the code in the table, otherwise we need to perform the recursion: increase the code length, add a 0 in the least significant bit and do the left branch, then change that 0 to a 1 and do the right branch.
I would start by making compute_code_table recursive, this allows you to easily traverse the tree.
Secondly, it helps for every task or assignment to search online for some sources which explain (in pseudo-code or not) how to do your specific task. In this case, this yields the following explanation:
To generate a huffman code you traverse the tree to the value you
want, outputing a 0 every time you take a lefthand branch, and a 1
every time you take a righthand branch. (normally you traverse the
tree backwards from the code you want and build the binary huffman
encoding string backwards as well, since the first bit must start from
the top).
siggraph.org
In C, this could be implemented as such:
int compute_code_table_for_node(tree_t tree, node_t target_node, node_t current_node, int code_table) {
// Check for target
if ( current_node == target_node ) {
// Found target
return code_table;
}
// Check if end-node
if ( current_node->left == NULL && current_node->right == NULL ) {
// Is an end node
return -1;
}
// Try left
int left = compute_code_table_for_node(tree, target_node, current_node->left, code_table << 1 + 0);
// Try right
int right = compute_code_table_for_node(tree, target_node, current_node->right, code_table << 1 + 1);
// Find which path was taken
if ( left == -1 ) {
// Left path didn't find it, so it must be the right path:
return code_table << 1 + 1;
} else {
// Left path found it
return code_table << 1 + 0;
}
}
Then you only have to call compute_code_table_for_node(tree, node, tree->head, 0) for every node in the tree.
This piece of code won't work for your specific case, so you will have to rewrite it.

Recursive code for a tree function?

I have a function that returns the first node of a tree,
node* primeiro(tree r){
while(r->left != NULL){
r = r->left;
}
return r;
}
BTW, the percuss is made in order. So the function returns the leftmost leaf of the tree and the function presumes that the tree is not empty. How can I implement this in a recursive way?
node* primeiro (tree r) {
while (r->left != NULL) {
r = primeiro (r->left);
}
return r;
}
This is not working.
The problem is in using while. You need simple recursion termination condition.
node* primeiro (tree r) {
if (r->left != NULL) {
r = primeiro (r->left);
}
return r;
}
Instead of using condition r->left != NULL for while loop, check it for true or false. (that will be base condition for the termination of recursion).
When we speak of "recursive functions", we usually mean "functions that use recursion to loop"...
Both of your functions are using while to loop. You should focus on transforming that while loop into a recursive function call.
Consider this loop:
int fubar(int x) {
while (x > 0) {
x--;
}
return x;
}
It transforms into this:
int fubar(int x) {
if (x > 0) {
return fubar(x - 1);
}
return x;
}
Notice how similar the two are. The differences are:
You're changing x not directly but by passing a different value of x in
Your loop test is in an if statement, not while...
Again, you're not looping using while; instead you should be calling fubar again, passing in a new value and returning its result.
Important note: There could be significant benefits to ensuring every recursive function call is followed immediately by a return (without any intermediate calculations required).
When iteration is being replaced with recursion, it may be easier to derive the right code by beginning with the infinite recursive loop:
node* primeiro(tree r){
/* What goes in the recursive loop body? */
return primeiro(r);
}
You can now ask under what would the next value of the iteration, and when does the loop stop. The next value is pretty straight forward.
node* primeiro(tree r){
/* When does the recursive loop stop? */
r = r->left;
return primeiro(r);
}
From the while loop logic, the loop stops when r->left is NULL. At that point, you would return r.
node* primeiro(tree r){
if (r->left == NULL) return r;
r = r->left;
return primeiro(r);
}

bitwise right shift affecting another short

I am using bitwise operators to shift the binary value of shorts within a linked list. The function is recursive and after an arbitrary number of occurrences, my right shift seems to affect the value of a short in the next link despite me not pointing to this link at all at this point of the function. Here is my code :
static void move_right(t_tetri *piece) {
int i;
i = 0;
piece->x_offset++;
while (i < piece->height) {
piece->shape[i] = piece->shape[i] >> 1;
i++;
}
}
int ft_solve(t_map *map, t_tetri *list) {
if (list == NULL) return (1);
while (list->y_offset + list->height <= map->size) {
while (list->x_offset + list->width <= map->size) {
if (put_tetri(map, list)) {
set_piece(map, list);
if (ft_solve(map, list->next)) return (1);
else unset_piece(map, list);
}
move_right(list);
}
reset_piece(list);
}
list->y_offset = 0;
return (0);
}
piece->shape is an array containing 4 short but I'm mostly concerned about the first of these here. In certain cases (not all) when I go through the move_right function the value of piece->next->shape[0] is shifted in the same way, which poses a big problem for the next recursion of ft_solve.
Would anyone have any idea?
I can post more of my code if necessary, I'm not really used to ask questions here so if you need more information I'm ready to add it.

C: AVL tree search method for a certain value

I'm trying to write a function that searches in an AVL tree after a certain value and returns how many nodes contain the searched value.
Here it's my struct :
struct building{
int id;
char* streetName;
int streetNumber; };
And this is my search function :
void searchAfterStreetName(node* root, char* searchedStreet){
int counter = 0;
if (root){
if (strcmp(searchedStreet, root->info->streetName) < 0){
return searchAfterStreetName(root->left, searchedStreet);
}
else if (strcmp(searchedStreet, root->info->streetName) > 0){
return searchAfterStreetName(root->right, searchedStreet);
}
else{
if (strcmp(searchedStreet, root->info->streetName) == 0){
counter = counter + 1;
printf("%d\n", counter);
}
}
}
else{
printf("Not found");
}
}
Basically, what I want to do is to perform a search in an AVL Tree after the street name and everytime the searched value is contained in a node I will increment the value of the counter and print out the total value at the end of the search on the console.
The search function works well until I add the counter. It enters in an infinite loop. Please help !!!

Pre/In/Postfix traversal in C including an Array

I would like to implement functions where I perform a pre, in and postorder traversal of an existing binary tree.
these traversals should then be displayed by a predefined test function
here's what i got so far for the preorder traversal
uint64_t i = 0;
int *binarytree_prefix(binarytree *tree) {
uint64_t *prefixArray = malloc(inputArrayLength_helper * sizeof(uint64_t));
prefixArray[i] = tree->value;
i++;
if (tree->left != NULL) {
return (binarytree_prefix(tree->left));
}
if (tree->right != NULL) {
return (binarytree_prefix(tree->right));
}
}
what I thought about it that it would insert the value of the current node into the array and then increent the position within the array and do a recursion on the left and then the right tree
however this does not work.
i hope someone is able to help me to make it running
What i did was a depth first search with a preorder traversal and then included the array to fill it with the current value
test function within main:
int *prefixArray = bintree_prefix(tree);
printf("Prefix notation : ");
for(uint64_t i = 0; i < inputArrayLength; i++) {
printf(" %d", prefixArray[i]);
}
printf("\n");
free(prefixArray);
ok after a few different variations of the code i finally got the right solution
for those interested
int *bintree_prefix(bintree *tree)
{
int *prefixArray = malloc(17*sizeof(uint64_t));
return (bintree_prefix_visited(tree, prefixArray));
}
int bintree_prefix_visited(bintree *tree, int *prefixArray)
{
if (tree!=NULL)
{
prefixArray[a]=tree->value;
a++;
bintree_prefix_visited(tree->left, prefixArray);
bintree_prefix_visited(tree->right, prefixArray);
}
return prefixArray;
}

Resources