I am trying to insert node in a binary search tree, I am getting an access voilation error at line if(ptr->data== item) in searchNode() function. How can I remove it. I am new to debugging.
I am first trying to insert few nodes and then display them using display function. During insertion the program searches for the appropriate position of the node to be inserted and then inserts it. Program simply returns if node already exists.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct node
{
int data;
struct node* left;
struct node* right;
};
void searchNode(struct node* root,int item,struct node* loc,struct node *par)
{
struct node * ptr,*save;
if(root==NULL)
{
loc=NULL;
par=NULL;
return;
}
else
{
if(item==root->data)
{
par=NULL;loc=root; return;
}
else if(item < root->data)
{
save=root;ptr=root->left;
}
else if(item > root->data)
{
save=root;ptr=root->right;
}
while(ptr!=NULL)
{
if(ptr->data == item )
{
loc=ptr;
par=save;
return;
}
else if(ptr->data > item )
{
save=ptr;
ptr=ptr->left;
}
else
{
save=ptr;ptr=ptr->right;
}
}
loc=NULL;
par=save;
}
}
void insertNode(struct node* root,int item, struct node * loc)
{
struct node* par,*newNode;
searchNode(root,item,loc,par);
if(loc!=NULL)
return;
newNode=(struct node *)malloc(sizeof(struct node));
newNode->left=NULL;newNode->right=NULL;
if(par==NULL)
{
root=newNode;
}
else if(item< par->data)
{
par->left=newNode;
}
else if(item> par->data)
{
par->right=newNode;
}
}
void display(struct node* t, int level)
{
int i;
if(t)
{
display(t->right,level+1);
printf("\n");
for(i=0;i<level;i++)
printf(" ");
printf("%d",t->data);
display(t->left,level+1);
}
}
int main()
{
int n,data,i;
struct node* root,*loc;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&data);
insertNode(root,data,loc);
}
display(root,1);
getch();
return 0;
}
You are calling your insert method as:
insertNode(root,data,loc);
and the root is passed by value as a result, any changes made to root in the insertNode method will not be visible in main. Since your root in main is uninitialized, the same gets passed to display where you try to dereference the uninitialized pointer leading to undefined behavior.
To fix this you either pass the address of root to insertNode function or return the changed root from the function.
Related
This is the function which I am using for BST inorder Traversal
void inOrder(struct node* root)
{
if(root==NULL)
{
return;
}
inOrder(root->left);
printf("Key:%d,Pointer:%p\n",root->key,root);
inOrder(root->right);
}
The structure for the same is
struct node{
int key;
struct node *left,*right;
};
When I run the function I get two 0 extra elements for the following inserts:
root=insert(root,7);
insert(root,4);
insert(root,10);
insert(root,3);
insert(root,5);
insert(root,1);
insert(root,2);
insert(root,0);
insert(root,8);
insert(root,14);
insert(root,6);
insert(root,9);
insert(root,16);
insert(root,12);
insert(root,15);
insert(root,17);
inOrder(root);printf("\n");
And the insert function is given below:
struct node *insert(struct node * root,int ele)
{
struct node *temp=newNode(ele);
struct node *tree=root;
struct node *saver;
if(root==NULL)
{
root=temp;
}
else
{
while(tree!=NULL)
{
saver=tree;
if(ele<tree->key)
tree=tree->left;
else
tree=tree->right;
}
if(ele<saver->key)
{
saver->left=temp;
}
else
{
saver->right=temp;
}
}
return saver;
}
The output shows two 0s apart from the main elements, which I added. I have recently learned the Binary-Search-Tree, and I tried to implement it, Can someone please help me rectify this error. Thank you in advance
in insert
if(root==NULL)
{root=temp;
}
must be
if(root==NULL)
{
saver=temp;
}
because you return saver (not initialized in your version)
I suppose also in your main the code is not what you give but something like
struct node * root = NULL;
root=insert(root,7);
insert(root,4);
...
If I define newNode like that :
struct node * newNode(int ele)
{
struct node * r = malloc(sizeof(struct node));
r->key = ele;
r->left = r->right = NULL;
return r;
}
and I do the other changes :
pi#raspberrypi:/tmp $ gcc -g -pedantic -Wextra n.c
pi#raspberrypi:/tmp $ ./a.out
Key:0,Pointer:0xf04078
Key:1,Pointer:0xf04058
Key:2,Pointer:0xf04068
Key:3,Pointer:0xf04038
Key:4,Pointer:0xf04018
Key:5,Pointer:0xf04048
Key:6,Pointer:0xf040a8
Key:7,Pointer:0xf04008
Key:8,Pointer:0xf04088
Key:9,Pointer:0xf040b8
Key:10,Pointer:0xf04028
Key:12,Pointer:0xf040d8
Key:14,Pointer:0xf04098
Key:15,Pointer:0xf040e8
Key:16,Pointer:0xf040c8
Key:17,Pointer:0xf040f8
The full code is :
#include <stdio.h>
#include <stdlib.h>
struct node{
int key;
struct node *left,*right;
};
void inOrder(struct node* root)
{
if(root==NULL)
{return;}
inOrder(root->left);
printf("Key:%d,Pointer:%p\n",root->key,root);
inOrder(root->right);
}
struct node * newNode(int ele)
{
struct node * r = malloc(sizeof(struct node));
r->key = ele;
r->left = r->right = NULL;
return r;
}
struct node *insert(struct node * root,int ele)
{
struct node *temp=newNode(ele);
struct node *tree=root;
struct node *saver;
if(root==NULL)
{
saver=temp;
}
else
{
while(tree!=NULL)
{
saver=tree;
if(ele<tree->key)
tree=tree->left;
else
tree=tree->right;
}
if(ele<saver->key)
{
saver->left=temp;
}
else
{
saver->right=temp;
}
}
return saver;
}
int main()
{
struct node * root = NULL;
root=insert(root,7);
insert(root,4);
insert(root,10);
insert(root,3);
insert(root,5);
insert(root,1);
insert(root,2);
insert(root,0);
insert(root,8);
insert(root,14);
insert(root,6);
insert(root,9);
insert(root,16);
insert(root,12);
insert(root,15);
insert(root,17);
inOrder(root);printf("\n");
}
i was trying to do tree traversal.(per-order,in-order,and post-order)
here is my code.
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node* left;
struct node* right;
};
void Insert(struct node* root,int item)
{
struct node* parent;
struct node* NewNode = (struct node*)malloc(sizeof(struct node));
NewNode->left = NULL;
NewNode->data = item;
NewNode->right = NULL;
if (root == NULL)
root = NewNode;
else
{
parent = root;
while (1)
{
if (parent->data>item)
{
if(parent->left == NULL)
{
parent->left = NewNode;
return;
}
parent = parent->left;
}
if (parent->data<item)
{
if(parent->right == NULL)
{
parent->right = NewNode;
return;
}
parent = parent->right;
}
}
}
}
void pre(struct node *newNode)
{
if(newNode!=NULL)
{
printf("%d ",newNode->data);
pre(newNode->left);
pre(newNode->right);
}
}
void in(struct node *newNode)
{
if(newNode!=NULL)
{
in(newNode->left);
printf("%d ",newNode->data);
in(newNode->right);
}
}
void post(struct node *newNode)
{
if(newNode!=NULL)
{
post(newNode->left);
post(newNode->right);
printf("%d ",newNode->data);
}
}
int main(void)
{
int num,i;
printf("\nHow many Numbers you wanna Enter in tree:\t");
scanf("%d",&num);
int numArr[num];
printf("\nEnter the numbers: \n");
struct node* root = NULL;
for (i=0;i<num;i++)
{
scanf("%d",&numArr[i]);
Insert(root,numArr[i]);
}
printf("\nPre order traversal is:\n");
pre(root);
printf("\nIn order traversal is:\n");
in(root);
printf("\nPost order traversal is:\n");
post(root);
}
i think i have problem with inserting the value because when i run the code the output is just empty.
could anyone explain me where m i going wrong?
at insert function m taking the root node and the item to be inserted as argument.
then i'm creating a new node using malloc.
inserting data to the new node and left, right is null as left and right is currently not pointing to any nodes.
then checking if root is null or not. if it is null m assigning the new node to root node.
if root is not null.
(i should not loose the root so i am copying root to parent and using that.)
m checking if the data is less than root or not. if it is less m going to the left of root if left of root is null m inserting the address of new node there if it is not null m just going left and left until it becomes null.
m doing the same thing(just going right) if data is greater than the value in root.
my explanation tells me m going on the right path.
but my code tell me a different story.
this is the correct answer thanks to everyone for help.
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node* left;
struct node* right;
};
void Insert(struct node** root,int item)
{
struct node* parent;
struct node* NewNode = (struct node*)malloc(sizeof(struct node));
NewNode->left = NULL;
NewNode->data = item;
NewNode->right = NULL;
if (*root == NULL)
*root = NewNode;
else
{
parent = *root;
while (1)
{
if (parent->data>item)
{
if(parent->left == NULL)
{
parent->left = NewNode;
return;
}
parent = parent->left;
}
if (parent->data<item)
{
if(parent->right == NULL)
{
parent->right = NewNode;
return;
}
parent = parent->right;
}
}
}
}
void pre(struct node *newNode)
{
if(newNode!=NULL)
{
printf("%d ",newNode->data);
pre(newNode->left);
pre(newNode->right);
}
}
void in(struct node *newNode)
{
if(newNode!=NULL)
{
in(newNode->left);
printf("%d ",newNode->data);
in(newNode->right);
}
}
void post(struct node *newNode)
{
if(newNode!=NULL)
{
post(newNode->left);
post(newNode->right);
printf("%d ",newNode->data);
}
}
int main(void)
{
int num,i;
printf("\nHow many Numbers you wanna Enter in tree:\t");
scanf("%d",&num);
int numArr[num];
printf("\nEnter the numbers: \n");
struct node* root = NULL;
for (i=0;i<num;i++)
{
scanf("%d",&numArr[i]);
Insert(&root,numArr[i]);
}
printf("\nPre order traversal is:\n");
pre(root);
printf("\nIn order traversal is:\n");
in(root);
printf("\nPost order traversal is:\n");
post(root);
}
Question: Create a linked list containing values in the ascending values. Then write functions addNew() which will accept a value from the user and then call addBegin() and addafterValue() functions to add the input value in the appropriate place
e.g. consider the list is like this:
12,15,20,26 then if the user enters values 8, 16 & 30 the list will look like this: 8,12,15,16,20,26,30.
My program:
#include<stdio.h>
typedef struct node
{
int data;
struct node *next;
}NODE;
NODE *start=NULL;
void append()
{
NODE *temp,*ptr;
temp=(NODE *)malloc(sizeof(NODE));
printf("Enter data:");
scanf("%d",&temp->data);
temp->next=NULL;
if(start==NULL)
start=temp;
else
{
ptr=start;
while(ptr->next!=NULL)
ptr=ptr->next;
ptr->next=temp;
}
}
void display()
{
NODE *ptr=start;
while(ptr!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
void addBegin(int val)
{
NODE *temp;
temp=(NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=start;
start=temp;
}
unsigned int addAfterValue(int val,NODE *ptr)
{
NODE *temp;
temp=(NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=ptr->next;
return temp;
}
void addNew()
{
int val;
unsigned int loc;
NODE *ptr=start;
printf("Enter value to add:");
scanf("%d",&val);
if(val<ptr->data) {
addBegin(val);
ptr=NULL;
}
while(ptr!=NULL) {
if(ptr->next!=NULL)
{
if(val<ptr->next->data)
{
addAfterValue(val,ptr);
ptr->next=loc;
ptr=NULL;
}
else
{
ptr=ptr->next;
}
}
if(ptr->next==NULL)
{
loc=addAfterValue(val,ptr);
ptr=NULL;
}
}
}
int main()
{
int ans;
do
{
printf("Enter [1]To append\n[2]To add new node\n[3]To display\n[0]To exit\n");
printf("Enter your choice:");
scanf("%d",&ans);
switch(ans)
{
case 1:
append();
break;
case 2:
addNew();
break;
case 3:
display();
break;
case 0:
break;
default:
printf("Wrong Input.Try again.");
}
}while(ans);
}
My doubt: The addBegin() function works perfectly. I think there's something wrong with addafterValue(). Can anyone help me by finding out my mistake?
Instead of passing the current pointer address.
Use the previous node pointer and assign to its next node.
void addAfterValue(int val,NODE *ptr)
{
NODE *temp = (NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=ptr->next;
ptr->next = temp;
}
Change the addNew function
void addNew()
{
int val;
NODE *ptr=start;
NODE *prev= NULL;
printf("Enter value to add:");
scanf("%d",&val);
if( ptr == NULL || val < ptr->data)
{
addBegin(val);
return;
}
else
{
prev = ptr;
ptr=ptr->next;
}
while( ptr != NULL)
{
if( val <= ptr->data)
{
addAfterValue(val,prev);
return;
}
else
{
prev = ptr;
ptr=ptr->next;
}
}
/* Control comes here if the entire list is scanned.... Now append it to the end using prev pointer, as the new node is greater than all of the existing nodes */
}
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
#include<string.h>
struct node{
char *name;
struct node *lchild;
struct node *rchild;
};
void find(char *str,struct node **root,struct node **loc,struct node **par)
{
struct node *ptr,*ptrsave;
*loc=NULL;
*par=NULL;
if(*root==NULL)
{
return;
}
if(!strcmp((*root)->name,str))
{
*loc=*root;
return;
}
ptrsave=NULL;
ptr=*root;
while(ptr!=NULL)
{
if(!strcmp(ptr->name,str)) break;
ptrsave=ptr;
if(strcmp(ptr->name,str)>0)
ptr=ptr->lchild;
else
ptr=ptr->rchild;
}
*loc=ptr;
*par=ptrsave;
}
void insert(struct node **p,char *str)
{
struct node *location,*parent,*temp;
find(str,&(*p),&location,&parent);
if(location!=NULL)
{
printf("Element already exists\n");
return;
}
temp=(struct node *)malloc(sizeof(struct node));
temp->name=strdup(str);
temp->lchild=NULL;
temp->rchild=NULL;
if(parent==NULL)
{
*p=temp;
return;
}
else
{
if(strcmp(parent->name,str)>0)
parent->lchild=temp;
else
parent->rchild=temp;
}
}
void inorder(struct node *root)
{
if(root!=NULL)
{
preorder(root->lchild);
printf("[%30s]\n",root->name);
preorder(root->rchild);
}
}
int main()
{
struct node *root=NULL;
insert(&root,"Crocin");
insert(&root,"Acetyl");
insert(&root,"Colchichine");
insert(&root,"Diclofenac_50mg");
insert(&root,"Diclofenac_25mg");
insert(&root,"Morphine Sulphate");
insert(&root,"Fentanyl");
insert(&root,"Dolo");
insert(&root,"Ibuprofen");
insert(&root,"Tramadol");
insert(&root,"Paracetamol");
inorder(root);
getchar();
return 0;
}
This is the code i am using for creating and inserting nodes in a binary search tree. After that i created recursive inorder function. but this is not giving the right ouput. I am not able to find error that is creating discrepancy. Can someone suggest where i am going wrong?
Change
void inorder(struct node *root)
{
if(root!=NULL)
{
preorder(root->lchild);
printf("[%30s]\n",root->name);
preorder(root->rchild);
}
to
void inorder(struct node *root)
{
if(root!=NULL)
{
inorder(root->lchild);
printf("[%30s]\n",root->name);
inorder(root->rchild);
}
You are using another function (preorder) (not listed in your code)
Here i have written a code which inserts numbers in Binary tree. But it gives segmentation fault error.
And also it says " note: expected ‘struct tree *’ but argument is of type ‘struct node *’" in line 8.
Here is the code :-
#include<stdio.h>
#include<stdlib.h>
struct tree{
int data;
struct tree *left;
struct tree *right;
};
struct tree* insert(struct tree* node, int data)
{
if(!node){
node=malloc(sizeof(struct tree));
node->data=data;
node->left=node->right=NULL;
return node;
}
else {
if(data>node->data){
node->right= insert(node->right,data);
return node;
}
else{
node->left= insert(node->left,data);
}
return node;
}
}
printtree(struct tree* node)
{
if(node){
printf("%d",node->data);
}
printtree(node->left);
printtree(node->right);
}
main()
{
int i,n;
struct tree *NODE;
NODE= insert(NODE,5);
NODE= insert(NODE,3);
NODE= insert(NODE,8);
printtree(NODE);
}
You use if( node ) but better to use if( node != NULL )
You use if( !node ) but better to use if( node == NULL )
It make code more readable.
You have so many mistakes - so ... I make it in my way (my code formating, etc.).
printtree(node->left); printtree(node->right); was outside if( node != NULL ){} so it try to get NULL->left and NULL->right
Tested - code works.
#include<stdio.h>
#include<stdlib.h>
struct tree{
int data;
struct tree *left;
struct tree *right;
};
struct tree* insert(struct tree* node, int data)
{
if( node == NULL ) {
node = malloc( sizeof(struct tree) );
node->data = data;
node->left = node->right = NULL;
} else {
if( data > node->data ){
node->right = insert(node->right, data);
} else {
node->left = insert(node->left, data);
}
}
return node;
}
void printtree(struct tree* node)
{
if( node != NULL ){
printf("%d\n", node->data);
printtree(node->left);
printtree(node->right);
}
}
int main()
{
struct tree *NODE = NULL;
NODE = insert(NODE, 5);
NODE = insert(NODE, 3);
NODE = insert(NODE, 8);
printtree(NODE);
return 0;
}
The local variable: struct tree* node; is not initialized, so the if (!node) test will have undefined behavior. Unless you assign it something or use it to hold a malloc'd node, the expression in the else block tries to dereference an uninitialized pointer.
You should also get used to idea that a tree can be considered a 'recursive' structure, so any node is a tree, and the top-level tree is simply a node. There's no good reason for two separate types here.
You are still making the error of passing NODE by value. If you want to modify it, you must use a pointer to that pointer.
#include<stdio.h>
#include<stdlib.h>
typedef struct t
{
int data;
struct t *left;
struct t *right;
}tree;
tree* insert(tree **node, int data)
{
if(!(*node))
{
*node=malloc(sizeof(tree));
(*node)->data=data;
(*node)->left=(*node)->right=NULL;
return *node;
}
else
{
if(data>(*node)->data)
{
(*node)->right = insert(&((*node)->right),data);
return *node;
}
else
{
(*node)->left = insert(&((*node)->left),data);
return *node;
}
}
}
void printtree(tree *node)
{
if(node)
{
printf("%d",node->data);
printtree(node->left);
printtree(node->right);
}
}
void freeMemory(tree *node)
{
if(node)
{
freeMemory(node->left);
freeMemory(node->right);
free(node);
}
}
int main()
{
tree *NODE = NULL;
NODE= insert(&NODE,5);
NODE= insert(&NODE,3);
NODE= insert(&NODE,8);
printtree(NODE);
freeMemory(NODE);
return 0;
}
Link: http://ideone.com/OpZWiC