Inorder traversal for binary search tree, shows some errors - c

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");
}

Related

free(data) tries to free the wrong address

I have implemented a tree with the nodes looking like that:
typedef struct node_s {
struct node_s *parent;
struct node_s *left;
struct node_s *right;
data_t *data;
}node_t;
with *data pointing to a struct of data with a key which is used to sort the tree.
when I add a new node it looks like this:
node_t *add_Item (node_t *root){ //root is the root of the tree
...
data_t *new_data;
new_data = calloc(1,sizeof(data_t));
if(!new_data){
... //Error handling
}
root = insert_Node(root, new_data);
... //modifying new_data
return root;
}
node_t insert_Node(node_t *root, data_t *data){
... \\tree traversing and searching
if(root->data->key == data->key){ \\if the key is already in the tree it should be replaced
data_t *temp_data = root->data;
root->data = data;
free(temp_data); \\freeing the old data
}
...
return root;
}
What I don't understand is that the free(temp_data) doesn't work. Additionally the debug information doesn't make sense to me:
temp_data = 0x0000024C856DA950
root->data = 0x0000024C856DA9D0
and the debug message: HEAP[Program.exe]: Invalid address specified to RtlValidateHeap( 0000024C856D0000, 0000024C856DA920 )
The address in the error message is always 0x30 smaller than temp_data.
Just if it helps anybody: Windows 10, Visual Studio
EDIT- minimal reproducable example
#include <stdio.h>
#include <stdlib.h>
typedef struct data_s {
long key;
}data_t;
typedef struct node_s {
struct node_s* parent;
struct node_s* left;
struct node_s* right;
data_t* data;
}node_t;
node_t* init_node(data_t* data) {
node_t* new_node;
if ((new_node = calloc(1, sizeof(node_t)))) {
new_node->data = data;
fprintf(stderr, "node created\n");
}
return new_node;
}
node_t* insert_node(node_t* root, data_t* data) {
node_t* node;
if (root) {
if (root->data->key == data->key) {
printf("This item alreay exists!\n%ld will be replaced!\n", data->key);
data_t* temp_data;
temp_data = root->data;
root->data = data;
free(temp_data);
}
else if (root->data->key > data->key) {
node = insert_node(root->right, data);
root->right = node;
node->parent = root;
}
else {
node = insert_node(root->left, data);
root->left = node;
node->parent = root;
}
}
else {
root = init_node(data);
}
return root;
}
int main(int argc, char** argv) {
data_t* data;
node_t* root = 0;
while (1) {
if (!(data = calloc(1, sizeof(data_t)))) {
return(EXIT_FAILURE);
}
printf("What is the key for the new data?\n");
scanf("%ld", &(data->key));
root = insert_node(root, data);
//there would be more editing of data afterwards
}
return(EXIT_SUCCESS);
}
This seems to work but I don't know why this works and my other progam not.

Stuck with branches of Tree

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);
}

Code to insert node at last position in C programming language

I am writing a code on linklist in C programming language. When I am using an online compiler my code is working fine but when I am using Codeblock to run the code, the code is not working. I am posting the code kindly provide me solution. My code is to add node in a linklist on the last position.
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node* Head;
void insert(int);
void print();
int main()
{
Head = NULL;
insert(2);
insert(3);
insert(4);
print();
return 0;
}
void insert(int a)
{
struct Node* temp1=(struct Node*)malloc(sizeof(struct Node));
temp1-> data = a;
temp1-> next = NULL;
if(Head == NULL)
{
Head = temp1;
return;
}
struct Node* temp = Head;
while(temp->next!= NULL)
{
temp = temp->next;
}
temp-> next = temp1;
}
void print()
{
struct Node* temp2=Head;
while(temp2 != NULL)
{
printf("%d \n", temp2->data);
temp2 = temp2->next;
}
return;
}
Here is how you can achieve what you want to do.
I suggest you to use a top-down approach when programming.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int info;
struct node *next;
};
struct node *Insert(struct node *, int);
void Print_List(struct node *);
void Remove_List(struct node *);
int main(int argc, char **argv)
{
struct node *head;
head = NULL;
head = Insert(head, 10);
head = Insert(head, 20);
Print_List(head);
Remove_List(head);
head = NULL;
return 0;
}
struct node *Create_New_Node(int);
struct node *Head_Insert(struct node *, int);
struct node *Queue_Insert(struct node *, int);
struct node *Insert(struct node *, int);
void Print_List(struct node *);
void Remove_List(struct node *);
struct node *Insert(struct node *top, int elem)
{
if(top == NULL)
{
top = Head_Insert(top, elem);
}
else
{
top = Queue_Insert(top, elem);
}
return top;
}
struct node *Create_New_Node(int elem)
{
struct node *new_node;
new_node = (struct node *)malloc(sizeof(struct node));
if(new_node != NULL)
{
new_node -> info = elem;
new_node -> next = NULL;
}
return new_node;
}
struct node *Head_Insert(struct node *top, int elem)
{
struct node *new_node = Create_New_Node(elem);
if(new_node != NULL)
{
new_node -> next = top;
}
return new_node;
}
struct node *Queue_Insert(struct node *top, int elem)
{
if(top != NULL)
{
if(top -> next != NULL)
{
top -> next = Queue_Insert(top -> next, elem);
}
else
{
struct node *new_node = Create_New_Node(elem);
if(new_node != NULL)
{
top -> next = new_node;
}
}
}
return top;
}
void Print_List(struct node *top)
{
while(top != NULL)
{
printf("\nInfo : %d\tAddress : %u\tNext link address : %u\n", top -> info, top, top -> next);
top = top -> next;
}
return;
}
void Remove_List(struct node *top)
{
if(top != NULL)
{
Remove_List(top -> next);
top -> next = NULL;
free(top);
}
return;
}
Sample output :
Info : 10 Address : 39149584 Next link address : 39149616
Info : 20 Address : 39149616 Next link address : 0

Inorder traversal is printing in wrong order

#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)

Binary Tree segmentation fault

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

Resources