Node value changing automatically in C - c

I'm creating a program for binary search trees and this is a function that I'm using. As seen in the output, the value of
root->rightChild is changing for unknown reasons and the program end without showing any errors.
typedef struct node * BST;
struct node
{
struct node *leftChild;
int data;
struct node *rightChild;
};
BST temp=NULL, ptr=NULL, root=NULL, prev=NULL;
BST newNode()
{
BST X;
X=(BST)malloc(sizeof(BST));
X->leftChild=X->rightChild=NULL;
return X;
}
void createBST(int elem)
{
temp=newNode();
temp->data=elem;
if(!root)
{
root=temp;
printf("\nroot-?rightChild= %p",root->rightChild);
printf("\nroot-?leftChild= %p",root->leftChild);
}
else
{
printf("\nroot-?rightChild= %p",root->rightChild);
printf("\nroot-?leftChild= %p",root->leftChild);
prev=NULL;
ptr=root;
while(ptr!=NULL)
{
prev=ptr;
ptr=(ptr->data<temp->data)?ptr->rightChild:ptr->leftChild;
}
if(prev->data<temp->data)
prev->rightChild=temp;
else
prev->leftChild=temp;
}
}
int main()
{
int choice;
while(1)
{
printf("\nPick a Binary Search Tree operation\n1) Create a Binary Search Tree\n2) Traverse the Binary Search Tree\n3) Seach for a KEY element in the Binary Search Tree\n4) Exit\n>| ");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
int num,elem;
printf("\nEnter the number of elements to be inserted into the Binary Search Tree: ");
scanf("%d",&num);
printf("\nEnter the elements to be inserted into the Binary Search Tree: ");
for(int i=1;i<=num;i++)
{
scanf("%d",&elem);
createBST(elem);
}
}
break;
case 2:
traverBST();
break;
case 3:
searchBST();
break;
case 4:
exitProgram();
break;
default:
printf("\nInvalid Choice\n");
}
}
return 0;
}
This is the output of the code:

This statement has a typo
X=(BST)malloc(sizeof(BST));
^^^
That is the call of malloc allocates a memory for a pointer to node instead of for a node itself.
There must be
X=(BST)malloc(sizeof( *X));
or
X=(BST)malloc(sizeof( struct node ));
As a result of the typo the program has undefined behavior.

Related

Data Structures - Linked list library in C

I'm new to C so I'm seeking help because I'm stuck.
After creating a linked-list library, from which I can add, delete and print all the nodes the user wants, I should add to the program an additional function of integer type and return a -1 if the value doesn't exist inside of the linked-list. If the value does exist inside the linked list, it should return the position of the element.
For example in this linked-list (a -> b -> c -> d -> NULL) if I want to know the position of c it should return me a 3, if I want to know the position of G it should return me -1
This is the program I was able to make until now:
#include <stdio.h>
#include <stdlib.h>
struct ListNode
{
char data;
struct ListNode *nextNode;
};
typedef struct ListNode node;
int main()
{
node *startNodePtr= NULL;
int choice;
char value;
printf("\t\t\tLIST OF CHARACTERS\n");
do
{
printf("\n1.Add New Node \t2.Delete Node \t3.Print Current List \t4.QUIT\n\n");//user friendly interface
scanf("%d",&choice);
switch(choice)
{
case 1: printf("Enter Character: ");
scanf("\n%c",&value);
insertNode(&startNodePtr,value);//calling the function to add a node
break;
case 2: printf("Delete Character: ");
scanf("\n%c",&value);
deleteNode(&startNodePtr,value);//calling the function to remove a node
break;
case 3: printList(startNodePtr);//calling the function to list the nodes
break;
case 4: continue;//if we type 4 it won't show the default answer
default:printf("\t\tINVALID ANSWER! Please type 1. 2. 3. or 4.\n");// in case we type any other character that is not 1, 2, 3 or 4. In this way the program will not crash
break;
}
} while(choice!=4);//keep adding or deleting nodes until we enter 4 which refers to "QUIT"
return 0;
}
void insertNode(node **sPtr, char add)//function to add a node
{
node *newPtr;
node *curPtr;
node *prevPtr;
newPtr=malloc(sizeof(node));
newPtr->data=add;
newPtr->nextNode=NULL;
prevPtr=NULL;
curPtr=*sPtr;
while(curPtr!=NULL)
{
prevPtr=curPtr;
curPtr=curPtr->nextNode;
}
if (prevPtr==NULL)
{
*sPtr=newPtr;
}
else
{
prevPtr->nextNode=newPtr;
}
}
void deleteNode(node **sPtr, char remove)//function to remove a node
{
node *curPtr;
node *prevPtr;
curPtr=*sPtr;
prevPtr=NULL;
if(curPtr->data==remove)
{
*sPtr=curPtr->nextNode;
free(curPtr);
return;
}
while (curPtr!=NULL)
{
if (curPtr->data==remove)
{prevPtr->nextNode=curPtr->nextNode;
free(curPtr);
return;}
else
{prevPtr=curPtr;
curPtr=curPtr->nextNode;}
}
}
void printList(node *sPtr)//function to list the nodes
{
if (sPtr==NULL)
{
printf("The list is empty!\n");
}
else
{
while (sPtr!=NULL)
{
printf("\n%c-->", sPtr->data);
sPtr=sPtr->nextNode;
}
} printf("NULL\n\n");
}
You have basically solved it already, you just have to count the number of iterations until you find the correct element.
int search(struct ListNode *node, char data) {
int position = 1;
// List is empty
if (node == NULL) {
return -1;
}
while (node != NULL) {
if (node->data == data) {
return position;
}
position++;
node = node->nextNode;
}
// Element was not in the list
return -1;
}

Memory allocation to a Node with Character array in a Linked list

OK, this is a simple single linked list program in c
struct node
{
int id;
char name[20];
int sem;
struct node *link;
};
typedef struct node* Node;
Node getnode()
{
Node temp=(Node)(malloc(sizeof(Node)));
if(temp==NULL)
printf("\n Out of memory");
return temp;
}
Node ins_pos(Node first)
{
Node temp=getnode();
printf("\n Enter id ");
scanf("%d",&temp->id);
printf("\n Enter name ");
scanf("%s",temp->name);
printf("\n Enter semester ");
scanf("%d",&temp->sem);
if(first == NULL)
{
temp->link=NULL;
return temp;
}
else
{
int pos,i;
printf("\n Enter position: ");
scanf("%d",&pos);
if(pos == 1)
{
temp->link=first;
return temp;
}
else
{
Node prev=NULL,cur=first;
for(i=1; i<pos; i++)
{
if(cur==NULL)
break;
prev=cur;
cur=cur->link;
}
if(cur==NULL && i < pos)
printf("\n Position invalid");
else
{
prev->link=temp;
temp->link=cur;
}
return first;
}
}
}
Node del(Node first)
{
if(first==NULL)
printf("\n List is Empty ");
else
{
Node temp=first;
printf("\n ID: %d was deleted",temp->id);
first=first->link;
free(temp);
}
return first;
}
void disply(Node first)
{
if(first==NULL)
printf("\n List is empty");
else
{
Node cur=first;
while(cur!=NULL)
{
printf("\n ID : ");
printf("%d",cur->id);
printf("\n Name : ");
printf("%s",cur->name);
printf("\n Semester : ");
printf("%d",cur->sem);
printf("\n\n\n");
cur=cur->link;
}
}
}
int main()
{
Node first=NULL;
int opt;
do
{
printf("\n QUEUE MENU\n 1.Insert at position \n 2.delete front\n 3.display\n 4.Exit \n\n Enter your choice : ");
scanf("%d",&opt);
switch(opt)
{
case 1 :first = ins_pos(first);
break;
case 2 :first = del(first);
break;
case 3 :disply(first);
break;
}
}while(opt!=4);
return 0;
}
When inserting a new node, Code Blocks Crashes at the malloc statement. How do I know? well, it crashes before asking "Enter ID". So, am I doing something wrong?
Another point here is, it works fine with only an integer field in node, the problem here maybe the character array.
In this function Node getnode() -
Node temp=(Node)(malloc(sizeof(Node)));
With the above malloc you allocate memory equal to size of Node which is of type struct pointer , and is not enough .Therefore ,you get a segmentation fault.
instead of this ,write like this -
Node temp=malloc(sizeof(*temp)); //also there is no need of cast
This will allocate memory equal to size of type to which temp points to i.e size equal to that of structure. Which is appropriate .
Some errors here.
malloc( sizeof( struct node ) );
Otherwise too little memory is allocated.
Do you include stdlib.h for malloc definition - that would cause this issue (no definition, defaults to int).
You need to use Node temp=(Node)(malloc(sizeof(*temp)));

C Program to copy one binary search tree to another

So, here i have come up with Binary search tree prgram, where i am creating 2 binary trees tmp and tmp2, where i am trying to copy whole tmp2 to tmp, the node which is taken as input from user. But i am getting some segmentation fault, also i am not so sure if the logic is right.
Here is the whole program, please lemme know where is it going wrong in t_cpy() or please just fix it for me..
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *rlink;
struct node *llink;
}*tmp=NULL,*tmp2=NULL,*tmp3=NULL;
typedef struct node NODE;
NODE *create();
void inorder(NODE *);
void insert(NODE *);
void t_cpy(NODE *,NODE *);
int main()
{
int n,m;
do
{
printf("\n1.create tree 1\n2.Insert element to tree1\n3.create tree 2\n4.Insert element to tree2\n5.Inorder tree1\n6.Inorder tree2\n7.Copy tree2 to tree1\n8.exit\n\n");
printf("\nEnter ur choice: ");
scanf("%d",&m);
switch(m)
{
case 1: tmp=create();
break;
case 2: insert(tmp);
break;
case 3: tmp2=create();
break;
case 4:
insert(tmp2);
break;
case 5: printf("\n\nInorder Tree1: ");
inorder(tmp);
break;
case 6: printf("\n\nInorder Tree 2: ");
inorder(tmp2);
break;
case 7: t_cpy(tmp,tmp2);
break;
case 8: return(0);
}
}while(n!=8);
return(0);
}
void insert(NODE *root)
{
NODE *newnode;
if(root==NULL)
{
newnode=create();
root=newnode;
}
else
{
newnode=create();
while(1)
{
if(newnode->data<root->data)
{
if(root->llink==NULL)
{
root->llink=newnode;
break;
}
root=root->llink;
}
if(newnode->data>root->data)
{
if(root->rlink==NULL)
{
root->rlink=newnode;
break;
}
root=root->rlink;
}
}
}
}
NODE *create()
{
NODE *newnode;
int n;
newnode=(NODE *)malloc(sizeof(NODE));
printf("\n\nEnter the Data ");
scanf("%d",&n);
newnode->data=n;
newnode->llink=NULL;
newnode->rlink=NULL;
return(newnode);
}
void t_cpy(NODE *t1,NODE *t2)
{
int val,opt=0;
NODE *temp;
if(t1==NULL || t2==NULL)
{
printf("Can not copy !\n");
}
inorder(t1);
printf("\nEnter the node value where tree 2 should be copied\n");
scanf("%d",&val);
temp=t1;
while(temp!=NULL)
{
if(val<temp->data)
temp=temp->llink;
else
temp=temp->rlink;
}
if(temp->llink!=NULL || temp->rlink!=NULL)
printf("Not possible to copy tree to this node\n");
else
{
printf("Copy tree to \n 1.Left Node \n 2.Right Node\n Enter your choice : ");
scanf("%d",&opt);
if(opt==1)
{
temp->llink=t2;
}
else if(opt==2)
{
temp->rlink=t2;
}
else
printf("Invalid choice\n");
}
printf("Tree1 after copying is\n");
inorder(temp);
}
void inorder(NODE *tmp)
{
if(tmp!=NULL)
{
inorder(tmp->llink);
printf("%d",tmp->data);
inorder(tmp->rlink);
}
}
EDIT : Thanks to #xaxxon , who helped me with this.
Just update the while to make it work :
while(temp!=NULL&&temp->data!=val)
{
if(val<temp->data)
temp=temp->llink;
else
temp=temp->rlink;
if(temp->llink==NULL && temp->rlink==NULL && temp->data!=val)
{
printf("Invalid Node value entered !\n");
//break;
return 0;
}
and, Now it works fine for if entered value is present in the tree.
Thanks :)
Among other possible problems, you traverse temp until it is null, and on the next line you dereference it.
while(temp!=NULL)
{
if(val<temp->data)
temp=temp->llink;
else
temp=temp->rlink;
}
if(temp->llink!=NULL || temp->rlink!=NULL)
printf("Not possible to copy tree to this node\n");
You most likely mean to break out of this loop if val == temp->data, but you don't. Also, you still need to check to see if temp is null after the loop in case you didn't find val in your tree. Most likely you just meant to say:
if(temp==NULL)
printf("Not possible to copy tree to this node\n");
Also, you can't ask which side of the found node the user wants to copy a tree to. If you have a binary search tree, it has to be the side where the value should go. If you say to copy it to the right side, but all the values are less than the node, it's no longer a BST. In fact, you can't even ask where the value should go and still have a binary search tree. Each node has to be traversed from the root of the tree you want to put the other tree into to maintain the BST mechanics.
When you first use insert(tmp) the value of tmp does not change after you call insert(). Pass the address of tmp to insert(), using a *root within it instead of root.

Inorder successor of Threaded Binary Tree

I am writing a c program to create threaded binary tree and then to find INORDER SUCCESSOR of a particular node. For this, i am displaying inorder sequence for the TBT constructed and then asking user to input the node to which successor is to be displayed.. I have written function to do this. But i am not getting successor for the FIRST NODE .. Last node's successor is 0 any ways its working fine.. Can any one help me fix this ?
Here is the whole program :
#include<stdio.h>
#include <stdlib.h>
struct tbtnode {
int data;
struct tbtnode *left,*right;
int lbit,rbit,flag;
int child;
}*root=NULL;
typedef struct tbtnode TBT;
TBT *insuc(TBT *t);
void inorder(TBT *);
void create(TBT *);
void create(TBT *root)
{
int x,op,flag,y;
flag=0;
char ch;
TBT *curr=root;
TBT *q,*p;
do
{
printf("\nCurrent node %d \n\n 1.Left Direction.\n\n2.Right Direction",curr->data);
printf("\nEnter ur choice :");
scanf("%d",&op);
switch(op)
{
case 1: if(curr->lbit==1)
{
printf("Enter left child of %d : ",curr->data);
scanf("%d",&x);
q=(TBT *)malloc(sizeof(TBT));
q->data=x;
q->lbit=q->rbit=1;
q->left=curr->left;
q->right=curr;
curr->left=q;
curr->lbit=0;
q->child=0;
flag=1;
}
else
curr=curr->left;
break;
case 2: if(curr->rbit==1)
{
printf("Enter right child of %d :",curr->data);
scanf("%d",&x);
q=(TBT *)malloc(sizeof(TBT));
q->data=x;
q->lbit=q->rbit=1;
q->left=curr;
q->right=curr->right;
curr->right=q;
curr->rbit=0;
q->child=1;
flag=1;
}
else
curr=curr->right;
break;
}
}while(flag==0);
}
void inorder(TBT *head)
{
TBT *t;
t=head->left;
printf("\n");
while(t->lbit==0)
t=t->left;
while(t!=head)
{
printf(" %d",t->data);
t=insuc(t);
}
}
TBT *insuc(TBT *t)
{
if(t->rbit==0)
{
t=t->right;
while(t->lbit==0)
t=t->left;
return(t);
}
else
return(t->right);
}
void inorder_successor(TBT *head,int x)
{
TBT *t;
t=head->left;
printf("\n");
while(t->lbit==0)
t=t->left;
while(t!=head)
{
t=insuc(t);
if(t->data==x)
{
t=insuc(t);
printf(" %d",t->data);
}
}
}
int main()
{
int op,x,n,i=0,item;
char ch;
TBT *head,*root,*succ; //here head indicates dummy variable
head=(TBT *)malloc(sizeof(TBT));
head->left=head;
head->right=head;
head->lbit=1;
head->rbit=1;
do
{
printf("\n****Threaded binary tree operations****");
printf("\n1)create\n2)inorder\n3)Successor\n4)exit");
printf("\nEnter ur choice: ");
scanf("%d",&op);
switch(op)
{
case 1:
printf("\nEnter Number Of Nodes :");
scanf("%d",&n);
printf("\nEnter root data: ");
scanf("%d",&x);
root=(TBT *)malloc(sizeof(TBT));
root->data=x;
root->lbit=root->rbit=1;
root->child=0;
root->left=head->left;
head->left=root;
head->lbit=0;
root->right=head->right;
for(i=0;i<n-1;i++)
create(root);
break;
case 2:
printf("\nInorder Traversal Is:\n");
inorder(head);
break;
case 3: printf("Enter the node to which successor is to be found\n");
scanf("%d",&item);
inorder_successor(head,item);
break;
case 4:
return(0);
break;
}
}while(op<=4);
return 0;
}
please fix - inorder_successor() function for me..
Thank you
You have many problems with your code. To start with you never check for NULL pointers. To continue, you have both a global and a local variable in main called root.
The last thing means that when you allocate memory for root in main, you allocate for the local variable, and the global variable will still be NULL.
There are also other things that look weird, like you assigning the left and right pointer of head to itself.
I think you need to lay it all out on paper first, both how you have it now and how you want it to be. It will help you to better visualize the tree.

Implementing BinarySearchTree using Single Linked List

I have the below code which I am using to implement BinarySearchTree. Somehow it doesn't build the binarytree.Can anybody help what is the issue ?
typedef struct BinarySearchTree
{
struct BinarySearchTree *left;
int nodeval;
struct BinarySearchTree *right;
}
BST;
BST *root=NULL;
void addrootnode(BST *,int );
void addnode(BST *,int );
void deletenode(int );
void printnodes();
main()
{
int nodeval;
char choice;
printf("\n r->rootnode \n a->add \n d->delete \n p->print \n e->exit\n");
while (1)
{
printf("\nEnter your choice:");
scanf("%c",&choice);
switch (choice)
{
case 'r':
printf("\nEnter the root node value to add: ");
scanf("%d",&nodeval);
addrootnode(root,nodeval);
break;
case 'a':
printf("\nEnter the node value to add: ");
scanf("%d",&nodeval);
addnode(root,nodeval);
break;
case 'd':
printf("\nEnter the node value to delete: ");
scanf("%d",&nodeval);
break;
case 'p':
//printf("\n");
printnodes(root);
break;
case 'e':
exit(0);
default:
break;
}
}
getchar();
}//end of main
//addrootnode
void addrootnode(BST *ptr,int num)
{
if(ptr==NULL)
{
ptr=(BST *) malloc(sizeof(BST));
ptr->left=NULL;
ptr->nodeval=num;
ptr->right=NULL;
root=ptr;
}
}
//add node
void addnode(BST *ptr,int num)
{
if(ptr==NULL)
{
ptr=(BST *) malloc(sizeof(BST));
ptr->left=NULL;
ptr->nodeval=num;
ptr->right=NULL;
}
else if(num < ptr->nodeval )
{
addnode(ptr->left,num);
}
else
{
addnode(ptr->right,num);
}
}
//delete functionality
void deletenode(int nodeval)
{
}
//print all nodes
void printnodes(BST *ptr)
{
if (ptr)
{
printnodes(ptr->left);
printf("%d\t",ptr->nodeval);
printnodes(ptr->right);
}
}
You should not use BST *ptr as argument to addnode. You try to assign a value to it but at this time ptr is a local variable to the function addnode an does not alter the intended left or right pointer of the parent node.
Try to think about using BST **ptr instead.

Resources