Need help with tree-printing code - c

I am trying to print this tree:
1
/ \
2 3
/ / \
4 5 6
In this way:
1
2 3
4 5 6
I wrote this code:
void print_g(Tree t)
{
Queue q=initQueue();
Tree tmp=initTree();
if(!isTreeEmpty(t))
enqueue(q,t);
while(!isQueueEmpty(q))
{
tmp=dequeue(q);
printf("%d ",*((int *)Root(tmp)));
if(!isTreeEmpty(subLeft(tmp)))
enqueue(q,subLeft(tmp));
if(!isTreeEmpty(subRight(tmp)))
enqueue(q,subRight(tmp));
}
}
But this code is printed like this:
123456
I can't think of an idea how to solve the print issue.
Can someone write the Pseudo Code??
Thanks.

After you add the children to the queue, create a fake tree node with the value being a newline character and add it to the queue.

You don't have any code to print a newline ('\n') after each generation of the tree.
You need to find some way to tell your program when a tree generation passes and then stick the '\n' in there.
Perhaps:
void print_g(Tree t)
{
Queue q=initQueue();
Tree tmp=initTree();
if(!isTreeEmpty(t))
enqueue(q,t);
int dist = distanceFromTop(t); // new function to tell us which generation we are in
while(!isQueueEmpty(q))
{
tmp=dequeue(q);
if (distanceFromTop(tmp) != dist) // have we changed generation from previous iteration?
printf("\n"); // if so, newline
dist = distanceFromTop(tmp);
printf("%d ",*((int *)Root(tmp)));
if(!isTreeEmpty(subLeft(tmp)))
enqueue(q,subLeft(tmp));
if(!isTreeEmpty(subRight(tmp)))
enqueue(q,subRight(tmp));
}
}
Just be sure that your Tree definition has a member to hold its own distanceFromTop and fill this value in during initTree() to keep the algorithm from getting too slow.

Related

Binary Tree nodes and relations to the parent [duplicate]

This question already has answers here:
C How to "draw" a Binary Tree to the console [closed]
(10 answers)
Closed 3 years ago.
I know how to code a binary search tree, and to traverse it in inorder, preorder or postorder fashion.
But, I want to know how I can know where the actual node is:
For example let's say we have the values: 70 90 50 60 80 40
So the root would be 70, 90 to its right, 50 to its left, 60 to 50's right and so on.
So if I were to print this inorder, it would be 40 50 60 70 80 90, increasing order pretty much.
I do this by doing this in the recursive traverse function:
traverse(root->left);
printf("%d ", root->data);
traverse(root->right);
But this doesn't let me know (as far as I know) where the node currently is.
Is there a way to print the tree like this?:
70
50 (70 L) 90 (70 R) // We know which parent the node is from and we know if it's the left or the right of it.
40 (50 L) 60 (50 R) 80 (90 L)
and so on.. if the tree is bigger.
I don't really know how I'd do it. Would I need to link them to their parents? But how would I know the right-left thing if I do just that? Or do I need to print the child when the iterator is on the parent still. Thank you in advance.
Edit: I looked up printing the tree by traversing level by level but I don't think I get to know the parent and the side of the node.. I am trying to implement some codes to c code and I always get crashes.
Seems you want to print the tree level by level, i.e.
level 0: node0
level 1: node1 (node0 L) node2 (node0 R)
level 2: ...
So you need a way to track the current level and the target level (i.e. the one you want to print). Also you need a way to track when there is "no more levels" (i.e. no more to print).
That can be done in many ways. The pseudo code below should give you an idea of one way to do it. It's not the most efficient way but it's pretty simple.
Something like:
bool btPrintLevel(node* root, int targetlevel, int currentlevel)
{
if (targetlevel == currentlevel) return false; // no need to go further down in levels
bool result = false;
result |= btPrintLevel(root->left, targetlevel, currentlevel + 1);
// psedo code
if ((currentlevel + 1 == targetlevel)
{
if (childern_exists)
{
printChildern(...)
result = true;
}
}
result |= btPrintLevel(root->right, targetlevel, currentlevel + 1);
return result;
}
Called like:
int level = 0;
while(btPrintLevel(head, level)) ++level;
This How to print elements from Binary Tree by level in c may also help. It doesn't do exactly what you want but with minor modifications you can achieve your goal.
Recursive algorithms are fine for depth-first traversing of trees, but less suitable for broadth-first. The latter can be done pretty efficiently using a FIFO (pseudo code):
push(fifo, { root, 0 });
while(!isEmpty(fifo))
{
node* n = pop(fifo);
print(n);
if(n->left)
push(fifo, { n->left, 'L' });
if(n->right)
push(fifo, { n->right, 'R'});
}
I've foreseen an additional field designating being left or right child of parent. If you your nodes have a link to their parent, you can instead decide upon n->parent->left == n ? 'L' : 'R'.
Leaving implementing the FIFO up to you (you'll find quite a number of questions here on SO about)...

Pointer to linkedlist randomly changing

For one of my school assignments I have to make my own stack library and a POSTFIX calculator.
The calculator has to make use of the stack library and do some calculations.
I am pushing two different numbers to my stack. Number 6 and 3. The header should point to the most recently added node (LIFO). So when 6 is added:
HEADER -> 6 -> NULL
When 3 is being added:
HEADER -> 3 -> 6 -> NULL
When I print the value of my header after adding '6' it's good. It's printing 6.
However, when I print the value of my header BEFORE adding '3' it's printing '3'. When it still should print 6.
So a summary of my problem:
When adding another node to my linkedlist, the header suddenly points to the newest node before even changing it.
You may understand me better with some code and debugging results.
Btw: Don't mind the typedefs, I don't like them. My teacher wants us to use it.
typedef struct stackObject* pStackObject_t;
typedef struct stackObject
{
void* obj;
pStackObject_t next;
} StackObject_t;
typedef struct stackMEta* pStackMeta_t;
typedef struct stackMEta
{
pStackObject_t stack;
size_t objsize;
int numelem; //number of elements
int handle; //welke stack
pStackMeta_t next;
} StackMeta_t;
int mystack_push(int handle, void* obj)
{
**DELETED NON RELATED CODE BASED ON FEEDBACK**
if (currentMeta->handle == handle)
{
pStackObject_t newObject = malloc(sizeof(StackObject_t));
newObject->obj = obj;
printf("%s%d\n", "Wanting to push int to stack: ", *(int*)obj);
//First node
if (currentMeta->stack == NULL)
{
currentMeta->stack = newObject;
currentMeta->stack->next = NULL;
printf("%s%d\n", " FIRST Curentmeta->stack pointing to ", *(int*)currentMeta->stack->obj);
return 0;
}
else
{
printf("%s%d\n", "NOT FIRST Currentmeta->stack pointing to ", *(int*)currentMeta->stack->obj);
newObject->next = currentMeta->stack;
currentMeta->stack = newObject;
printf("%s%d\n", "Currentmeta->stack ", *(int*)currentMeta->stack->obj);
printf("%s%d\n", "Currentmeta->stack->next ", *(int*)currentMeta->stack->next->obj);
printf("%s%d\n", "Succesful pushed int to stack: ", *(int*)currentMeta->stack->obj);
return 0;
}
}
return -1;
}
Terminal:
Created stack with handle: 1 and objsize 4 bytes
Wanting to push int to stack: 6
FIRST Curentmeta->stack pointing to 6
Wanting to push int to stack: 3
NOT FIRST Currentmeta->stack pointing to 3
Currentmeta->stack 3
Currentmeta->stack->next 3
Succesful pushed int to stack: 3
My unit tests are performing good with this code. My calculator does not, while it's the same function call.
I found out that it was working 50/50. Using the same input values in another program resulted in good things.
I changed the code to this:
pStackObject_t newObject = malloc(sizeof(StackObject_t));
newObject->obj = malloc(sizeof(currentMeta->objsize));
memcpy(newObject->obj, obj, currentMeta->objsize);
Now it's working fine. The previous code was somehow using the old values, while it was already out of scope. Thanks everyone for the help.

C - How to traverse a Huffman Tree and generate corresponding Huffman codes?

I'm currently working on a program that reads in text from standard input, creates a Huffman tree from the data, and then generates the Huffman codes for the symbols in the Huffman tree.
I'm able to create the Huffman tree, which consists of Tree Node structs that contain the symbol, the frequency of the symbol, the Huffman code for the symbol, and pointers to the let and right nodes. However, I'm kind of stuck on how to traverse the tree and modify each node's "code" according to where it is in the tree.
Essentially what I'm asking is how to traverse a binary tree while modifying a node's elements based on where it is in the tree.
Originally I tried something along the lines of:
void generateCodes (struct HuffTreeNode* root, unsigned long bitShift)
{
struct HuffTreeNode* current = root;
if (root != NULL)
{
current->code |= 0<<bitShift;
generateCodes(root->left,bitShift+1);
current->code |= 1<<bitShift;
generateCodes(root->right,bitShift+1);
}
}
However, that didn't work, and I'm kind of at a loss for what to try next. Any ideas?
You have formed the tree. SO now remains the traversing.
17
/\
/ 7
/ /\
10 / 3
/\ C4 /\
A6 B4 D1 E2
Now initilaly you just put them( the 0's or 1's) in array.Left child link - 1 right child link-0
So in the array you put a[currrent]=1 then call huffmancode(tree->left,current+1)
OR if going to right subtree a[current]=0 then call huffmancode(tree->right,current+1).
At reaching the leaf node print array.
Pseudocode: (printtree)
if (root->left exists)
{
a[current] = 0;
printtree(root->left, a, current + 1);
}
if (root->right exists)
{
a[current] = 1;
printtree(root->right, a,current + 1);
}
if (root is leaf)
{
print a[].
}
I assume that your tree is correctly (and optimally) built.
Each Huffman code is a path from the root to a leaf defining a symbol. You add a 0 when you traverse a left arc and a 1 when you traverse a right arc.
So, a way for getting a list of all the pairs symbol,code consists in traversing recursively the tree. You maintain the current path from the root to the current visited node and when you reach a leaf you generate the pair symbol (which would be stored in the leaf) and the current path.
A data structure for managing the current path is a stack.
So, an algorithm could be as follows:
void codes(struct Node * root, struct Stack * s)
{
if (is_leaf(root))
{
char symbol = // symbol stored in the node
char * code = // the reversed stack content; that is the code of current leaf
printf("symbol %c has code %s\n", symbol, code);
}
s->push('0');
codes(LLINK(root), s);
s->pop();
s->push('1');
codes(RLINK(root), s);
s->pop();
}
I leave to you the details of implementation of the stack and other meta-parts (is_leaf(), LLINK(root), ...).
You can improve the algorithm to generate bits
I hope will be helpful

Search and Inserting in a binary tree recursively

first of all happy new year. I was trying to fix a piece of code I've been stumped on for hours. (Note: I am not a solid coder.)
What I am trying to do is to write a function "searchInsert", which will take in a binary tree and some integer i. It will then try to find the integer i in the tree. If it's not there it is inserted into the tree.
Other information: If we do in fact find the integer in the tree, return a pointer pointing to the node of to it. If we do not find it as we said before, insert it in BUT return a pointer pointing to the root of the tree.
I also must do this recursively.
Now I have tested it using an arbitrary tree along with i = 98, as follows:
Before what it looks like.
4
/ \
2 6
/ \ / \
1 3 5 7
After, what it should look like:
4
/ \
2 6
/ \ / \
1 3 5 7
\
98
But my code doesn't seem to be working.
treelink searchInsert(treelink t, TreeItem i){
treelink keyNode = NULL;
if (t == NULL) {
t = insertTreeNode(t, i);
} else if(i < t->item){
keyNode = searchInsert(t->left,i);
} else if(i > t->item){
keyNode = searchInsert(t->right,i);
} else {
keyNode = t;
return keyNode;
}
return t;
}
Other important notes: treelink is a pointer to a binary tree. Assume insertTreeNode works as it was a function given to us.
Any help would be appreciated thanks.
Among other problems, you have lost all context when you realize that you have not found the item that you are looking for:
if ( t == NULL ) {
t = insertTreeNode(t, i) ;
}
So you are always calling insertTreeNode with NULL as the first argument.
While recursion is a great way to step through a tree, you might instead want to create a pointer and iterate through the tree, so that you have the original t around when you decide to call insert.
{
treelink ptr= t ;
while ( ptr )
{
if ( ptr-> item == i ) return ptr ;
ptr= ( ptr-> item > i ) ? ptr-> left : ptr-> right ;
}
return insertTreeNode( t, i ) ;
}
A new node is created, but it is not linked to the tree. You never change your left and right pointers.
what you need is to update the link after recursive call, e.g.:
else if (i < t->item) {
t->left = searchInsert(t->left, i);
} ...
But then of course you cannot simply return a pointer to a found item if it's found, otherwise it would break the tree. That's because the statement of your task is NOT recursive: you have to return either root or an existing (inner) node. So you might want to write a recursive function which e.g. always returns a pointer to the root, but also returns a pointer to a found item (through an additional treelink* argument).
Or maybe it would be simpler to split the function into two: search which returns a pointer to an existing node, and insert which returns a pointer to the root. Both of them would be recursive and quite simple.

Logical error for linked list in C

#include <stdio.h>
#include <stdlib.h>
#define UINT unsigned int
struct item
{
UINT time ; // time in tics which is used to order the list.
UINT id ; // penguin id number.
UINT event ; // event this item describes.
struct item *next ; // pointer to next item in list.
};
struct item *head=NULL;
struct item *trail=NULL;
void link_list(UINT time, UINT id, UINT event)
{
struct item *t=NULL;
static int i=0;
if(i==0)
{
head->time=time;
head->id=id;
head->event=event;
trail=head;
trail->next=NULL;
i++;
printf("Hello Word\n");
}
t=malloc(sizeof(struct item));
trail->next=t;
trail->time=time;
trail->id=id;
trail->event=event;
trail=t;
trail->next=NULL;
if(i!=0)
printf("I am \n");
}
int main(int argc, char *argv[])
{
UINT x[3]={4,5,7}, y[3]={40,50,60}, z[3]={100,900,500};
int i=0;
head=malloc(sizeof(struct item));
trail=head;
link_list(x[0], y[0], z[0]);
link_list(x[1], y[1], z[1]);
link_list(x[2], y[2], z[2]);
struct item *f=NULL;
f=head;
do
{
printf("trail: %d %d %d\n", f->time, f->id, f->event);
f=f->next;
}
while(f!=NULL);
return 0;
}
Good day,
I'm currently having a logical problem with my code implementation of my linked list logically. This code is the framework I am using to integrate it into a larger program which will use linked list so I need to get this right.
Basically what is happening is when I finally reach the do while loop which I use as a debugging line to see the contents of a linked list I will get this output on my command line:
trail: 4 40 100
trail: 5 50 900
trail: 7 60 500
trail: 0 0 0
I am expecting the output to be like this:
trail: 4 40 100
trail: 5 50 900
trail: 7 60 500
I have excluded the other printf's in my code as they are just used to check if I am indeed going through my functions properly. Also this might be unrelated but is there a better debugger for c under linux? Because the built in debugger goes crazy when it steps into a malloc command so I have to debug all programs inside my head. :(
If by built-in debugger you mean gdb, you can tell it to step over malloc(); if your program crashes in malloc, though, you have run into a memory allocation or use bug in your program.
One apparent bug is that you do not initialize "t" correctly in link_list(), and in particular t->next is garbage, and your program will probably crash when it tries to follow it. I think you mean to set t->time, t->id etc., not trail->time.
The best way to append to a linked list is usually to have a separate function that returns a new list item with all the fields initialized, and then in the routine to append, just manipulate pointers. It also helps if your list head is just a pointer, not a struct, but that's a style issue.
Best of all is to use a library that supplies linked lists for you, but that's no good if you are learning about linked lists!
You're appending a new node to the tail, then writing in your datum to the tail node, then moving the tail pointer to the new node:
t=malloc(sizeof(struct item));
trail->next=t;
trail->time=time;
trail->id=id;
trail->event=event;
trail=t;
trail->next=NULL;
t is set to a new node.
the next pointer of the current list tail is set to point to t
the time, id, and event fields of the node pointed by tail are written.
tail reference is now moved to t, which still contains no data.
There are a plethora of things that can improve this code, starting with using modular design for a "list" management, but this is your immediate problem.

Resources