Implementing the Binary Tree in C - c

I am trying to implement the Binary tree in C.Firstly inserting the values and then traversing them into the Preorder.But when i call the function preorder() then it's giving me infinite loop with only last value inserted.
I am using following code:
struct node* insert(struct node *root,int num);
void preorder(struct node *root);
struct node *root=NULL;
int count=1;
struct node {
struct node *lchild;
struct node *rchild;
int data;
};
int main(){
root=insert(root,1);
//root=insert(root,2);
preorder(root);
return;
}
struct node* insert(struct node *root,int num){//insert a node into tree
//struct node *q;
if(root==NULL)
{
root=(struct node*)malloc(sizeof(struct node));
root->data=num;
root->lchild=NULL;
root->rchild=NULL;
//root=q;
count++;
}
else{
if(count % 2==0){
root->lchild=insert(root->lchild,num);
}
else{
root->rchild=insert(root->rchild,num);
}
}
return(root);
}
void preorder(struct node *root){
while(root!=NULL){
printf("%d\t",root->data);
preorder(root->lchild);
preorder(root->rchild);
}
}
here i am inserting only 1 value initially but the bug occurs.So in insert() there should not be any mistake,something correction should be done in preorder() or main()..what it can be?

I am not sure what preorder() should do, but this line causes the endless loop:
while(root!=NULL){
I guess you meant to write if not while

You need an if statement not a while statement in your preorder function.
while(root!=NULL){ //This is causing the infinite loop
In the loop body, you do not change the root pointer at any point so, if the condition is ever true, which it is for the root element, it will never come out of the loop.
It should instead be :
if(root!=NULL){

You have to write if rather than while so that the recursive loop had an base condition and it ends somewhere.
In your code instead of writing if(root!=NULL) write while(root!=NULL)

Related

linked list: how to return the whole linked list after insterting

I am trying to return the head of a linked list in the function Insert of the following program. However, it is failing with compilation error.
Can anyone please tell me what wrong I have done:
#include<stdio.h>
#include<stdlib.h>
struct ListNode
{
int data;
struct ListNode *next;
};
int ListLength(struct ListNode *head)
{
int count = 0;
struct ListNode *temp=head;
while(temp!=NULL)
{
count++;
temp=temp->next;
}
return count;
}
struct ListNode *Insert(struct ListNode *head, int value, int pos)
{
struct ListNode *temp,*curr;
curr=head;
int k=1;
temp=(struct ListNode *)malloc(sizeof(struct ListNode));
if(pos==1)
{
temp->data=value;
if(head==NULL)
{
temp->next=NULL;
head=temp;
}
else
{
temp->next=head;
head=temp;
}
}
else
{
while((curr!=NULL) && (k<pos))
{
k++;
curr=curr->next;
}
temp->data=value;
temp->next=curr->next;
curr->next=temp;
}
return head;
}
void printList(struct ListNode *head)
{
struct ListNode *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf(" ");
temp=temp->next;
}
}
int main
{
struct ListNode *head=NULL;
//head = NULL;
head=Insert(head,10,1);
//Insert(head,11,2);
printList(head);
return 0;
}
I am trying to return the head of the new linked list after the insertion. I don't know where I am going wrong. Thanks in advance for the help.
(i) Firstly, include int main(void) as mentioned in the comments.
(ii) Next, with your current code, when you try printing the list, you are going to be in an infinite loop and get a stack overflow.
To avoid this, increment the temp to point to the next node after each print.
So your print function should look like:
void printList(struct ListNode *head)
{
struct ListNode *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf(" ");
temp=temp->next; // this line is required
}
}
(iii) And in your main function, call the printList with an argument, that is the head of the node like this:
printList(head);
(iv) And don't forget to return the count in your finding the length of the list function. Add the return statement at the end of your ListLength function:
return count;
(v) Your current code does not handle a case when head is NULL, and user wants to insert at a position greater than 1. Or more generally, when a user wants to insert at a position that is greater than the current list's length.
While you trust such an input would not be given, always handle such exceptions (you would probably get a SEGMENTATION FAULT here when trying to access memory of null nodes).
To handle this, you can add a check at the start of the Insert function like,
int lenList = ListLength(head);
if (lenList < pos)
{
printf("Please provide a position less than %d to insert", lenList);
return 0; // don't proceed with inserting node with NULL pointers
}
If head is declared global you don't have to return it. (Sorry, my answer is short)

Inserting element in binary tree

The code is for inserting an element in a binary tree using level order traversal. I'll first tell u how it works. It first goes through the nodes in each level and if there is any node which doesn't have both children it inserts the node as a child to that node and it use's queue for storing and retrieving the nodes addresses. My problem is that every time I call the create function the root value which is passed is always null even after inserting a node the root value is not changed and it's still a null. I am unable to figure out what's wrong in this. Can anyone help me out?
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left,*right;
}*root;
struct queue
{
int capacity,rear,front;
struct node **qu;
};
void enqueue(struct queue *q,struct node *n)
{
q->front=(++(q->front))%q->capacity;
(q->qu)[q->front]=n;
if(q->rear==-1)
q->rear++;
}
struct node* dequeue(struct queue *q)
{
struct node *temp;
temp=q->qu[q->rear];
if(q->front==q->rear)
q->front=q->rear=-1;
else
q->rear=(++(q->rear))%q->capacity;
}
int isempty(struct queue *q)
{
return(q->rear==-1);
}
struct queue* create(unsigned int capacity)
{
struct queue *p;
p=(struct queue*)malloc(sizeof(struct queue));
p->capacity=capacity;
p->front=p->rear=-1;
p->qu=(struct node**)malloc(sizeof(struct node)*capacity);
return p;
}
void insert(struct node *root)
{
int n;
struct node *p,*q;
struct queue *tmp;
p=(struct node*)malloc(sizeof(struct node));
p->left=p->right=NULL;
scanf("%d",&n);
p->data=n;
if(root==NULL)
{
root=p;
return;
}
tmp=create(20);
enqueue(tmp,root);
while(isempty(tmp))
{
q=dequeue(tmp);
printf("%d %d\n",p,root);
if((!q->right)||(!q->left))
{
if(!q->right)
q->right=p;
else
q->left=p;
return;
}
else
{
enqueue(tmp,q->left);
enqueue(tmp,q->right);
}
}
}
void traverse(struct node *root)
{
if(!root)
return;
traverse(root->left);
printf("%d ",root->data);
traverse(root->right);
}
void main()
{
int i,n;
while(1)
{
printf("1.insert\n2.exit\n");
scanf("%d",&n);
switch(n)
{
case 2:goto end;
case 1:insert(root);
}
}
end:
traverse(root);
}
Thanks.
You've defined root as a global variable, but your insert function also defines it's own local version of root which takes precedence. Because you're passing root in by value rather than reference, changing it's value has no effect. You have two options on how to fix this.
Pass root by reference
You change insert to be void insert(struct node **root) and then replace all instances of root in the function with (*root). You'll also need to pass a pointer to root when you call it - insert(&root)
Return the new value of root
Change the return type to struct node * and make sure you return root at the end and at any point where you're already returning from the function. When you call it you'll assign the return value to root like root=insert(root)
Both are equally valid options.

Linked-list entering node at end each time while get input from user but something went wrong with any method

While trying to append node at the end of the linked list for each input given by user, there is something wrong with this code. I'm not getting it why this is happening? Could someone please point out what the problem is? If any one knows, please suggest me something to fix this bug?
#include <stdio.h>
//structure with two fields
struct node
{
int data;
struct node *next;
};
// data type definition
typedef struct node node;
//pointer to node which initially set to NULL
node *head=NULL;
//fucntion create and display
void create(int num);
void display();
main()
{
int n,i,num;
printf("enter the no of nodes : ");
scanf ("%d",&n);
for(i=0;i<n;++i)
{
printf("enter the data : ");
scanf("%d",&num);
create(num);
}
display();
}
//function create
void create(int num)
{
printf("\n");
if(head==NULL)
{
node *temp=(node*)malloc(sizeof(node));
temp->data=num;
temp->next=head;
head=temp;
}
else
{
node *temp1=head;
while(temp1!=NULL)
{
temp1=temp1->next;
}
node *ptr=(node*)malloc(sizeof(node));
ptr->data=num;
ptr->next=temp1->next;
temp1->next=ptr;
}
}
//function display()
void display()
{
node *temp;
temp=head;
printf("list is : ");
while(temp!=NULL)
{
printf("%d->",temp->data);
temp=temp->next;
}
}
This should help you!
void create(int num)
{
printf("\n");
if(head==NULL)
{
node *temp=(node*)malloc(sizeof(node));
temp->data=num;
temp->next=head;
head=temp;
}
else
{
node *temp1=head;
//Modified the condition to traverse till the last node, not the end of it
while(temp1->next != NULL)
{
temp1=temp1->next;
}
node *ptr=(node*)malloc(sizeof(node));
ptr->data=num;
ptr->next=temp1->next;
temp1->next=ptr;
}
}
(Note: there might be other issues in the program, I have not run it)
I'm looking at this part of the create function
node *temp1=head;
while(temp1!=NULL)
{
temp1=temp1->next;
}
node *ptr=(node*)malloc(sizeof(node));
ptr->data=num;
ptr->next=temp1->next;
temp1->next=ptr;
And it seems like you iterate over the list until you reach the end. At which point temp1 == NULL. But then you try to access temp1->next which should be an unaccessible memory (remember that you have just set it to NULL in the previous while-loop.
A debugger can help you with this situations (or even printing some information around). A widely used debugger is gdb.
(Note: there might be other issues in the program, I have not run it)

comiling error says "node undeclared" first use in program,although i made "node" a global one

#include<stdio.h>
#include<stdlib.h>
void print();
void insert(int);
struct node
{
int data;
struct node* next;
};
struct node* head;
void insert(int x)
{
struct node* temp=(node*)malloc(sizeof(node));
temp->data=x;
temp->next=head;
head=temp;
}
void print(void)
{
struct node* temp=head;
printf("the linked list is:\n");
while(temp!=NULL)
{
printf("%d ",temp->data);
temp=temp->next;
}
printf("\n");
}
main()
{
head=NULL;
printf("how many numbers?\n");
int n,x,i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("enter the number:\n");
scanf("%d",&x);
insert(x);
print();
}
return 0;
}
comiling error says "node undeclared" first use in program,although i made "node" a global one
this code is just for creating a linked list and adding user input values into the front of the linked list
insert(int x) function does the insertion work.
The error message is clear enough. In the function insert you should prepand the name node with the keyword struct.
void insert(int x)
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
^^^^^^ ^^^^^^
Another way to escape the error is to use a typedef. For example
typedef struct node
{
int data;
struct node* next;
} node;
I presume when you say "first use" you mean the first line of insert where you try to allocate a node. But it is not the first; outside of the definition, that is 3 lines above, where you declare head to be a struct node*. (also note that inside the definition you use struct node* as well.)
The problem is that you did not define node; you defined struct node, and that is what you need to use.
You might be confused by C++, in which a struct tag becomes a typedef. Try this:
typedef struct node {
int data;
struct node* next;
} node;
Now you can just use node instead of struct node everywhere. Easier to read and easier to type.

pre_order traversal using stack in c

I am not able to figure out why the program is printing only first 3 characters of the tree.
Please help.
#include <stdio.h>
#include <malloc.h>
struct node
{
struct node *left;
char data;
struct node *right;
};
struct node *buildtree(int);
void pre_order(struct node*);
char a[]={'a','b','c','d','e','f','g','\0','\0','h','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
int main()
{
struct node *root;
root = buildtree(0);
printf("pre order traversal:\n");
pre_order(root);
}
struct node *buildtree(int n)
{
struct node *temp = NULL;
if(a[n]!='\0')
{
temp=(struct node*)malloc(sizeof(struct node));
temp->left=buildtree(2*n+1);
temp->data=a[n];
temp->right=(2*n+2);
}
return temp;
}
void pre_order(struct node* root)
{
char stack[30];
struct node* ptr;
int top=1;
stack[1]=NULL;
ptr=root;
while(ptr!=NULL)
{
printf("%c",ptr->data);
if(ptr->right!=NULL)
{
top=top+1;
stack[top]=ptr->right;
}
if(ptr->left!=NULL)
ptr=ptr->left;
else
{
ptr=stack[top];
top=top-1;
}
}
}
I'm surprised that compiled
char stack[30];
should be replaced by
struct node* stack[30];
There might be other problems.
You wrote a nice recursive routine to build the tree, why not write a recursive routine to do a pre-order traversal. It would be much easier to understand.
Simply calling something "stack" won't make it behave as one. When you push something onto a stack, the existing values get pushed down, and the reverse is true for popping.
I'd start with a working stack implementation, preferably with own functions for pushing and popping stuff.

Resources