How malloc allocates space while inserting values to a binary search tree? - c

bellow there is a simple code for a binary search tree. It has 2 cases, the first one inserts values to the tree and the second one finds the preorder traversal of the tree.
My question has to do with the malloc function. In the first case we have this ptr = (struct node *)malloc(sizeof(struct node)); and lets say that the value that we want to insert is 50. I can see while debugging that ptr=50 and I can't understand how (struct node *)malloc(sizeof(struct node)) gives this result.
Also when we have struct node *ptr, *nodeptr, *parentptr as pointing variables to struct node inside the function and after that we have for example parentptr=NULL; this parentptr refers to the pointer *parentptr or its just a variable.
struct node
{
int data;
struct node* left;
struct node* right;
};
struct node* tree;
struct node*
insert(struct node*, int);
void
preorder(struct node*);
int
main()
{
int option, val;
struct node* ptr;
tree = NULL;
do {
printf("\n ******MAIN MENU******* \n");
printf("\n 1. Insert an element");
printf("\n 2. Preorder Traversal");
printf("\n 3. Exit");
printf("\n\n Enter your option : ");
scanf("%d", &option);
switch (option) {
case 1:
printf("\n Enter the value of the new node : ");
scanf("%d", &val);
tree = insert(tree, val);
break;
case 2:
printf("\n The elements of the tree are : \n");
preorder(tree);
break;
}
} while (option != 3);
getch();
return 0;
}
struct node*
insert(struct node* tree, int val)
{
struct node *ptr, *nodeptr, *parentptr;
ptr = (struct node*)malloc(sizeof(struct node));
ptr->data = val;
ptr->left = NULL;
ptr->right = NULL;
if (tree == NULL) {
tree = ptr;
tree->left = NULL;
tree->right = NULL;
} else {
nodeptr = tree;
parentptr = NULL;
while (nodeptr != NULL) {
parentptr = nodeptr;
if (val < nodeptr->data)
nodeptr = nodeptr->left;
else
nodeptr = nodeptr->right;
}
if (val < parentptr->data)
parentptr->left = ptr;
else
parentptr->right = ptr;
}
return tree;
}
void
preorder(struct node* tree)
{
if (tree != NULL) {
printf("%d\t", tree->data);
preorder(tree->left);
preorder(tree->right);
}
}

Related

linked list using double pointers

Using double pointers first time to create and display linked list
#include "stdio.h"
#include "stdlib.h"
struct node
{
int data;
struct node * next;
};
void Insert(struct node **, int , int );
void display(struct node *);
int main()
{
int c, data, position;
struct node* head;
do{
printf("Enter a choice :\n");
printf("1. Add an element.\n");
printf("2. Del an element.\n3.Display List.\n");
printf("4.Delete linked list.\n5.Exit.\n");
printf("Your Choice :");
scanf("%d",&c);
switch(c){
case 1 :
printf("\nEnter data and position :\n");
scanf("%d %d",&data,&position);
Insert(&head,data,position);
break;
case 2 :
break;
case 3 :
printf("Linked List : \n");
display(head);
break;
case 4 :
break;
case 5 :
exit(0);
default :
printf("Invalid Choice.\n");
break;
}
}while(1);
return 0;
}
void Insert(struct node **ptrhead, int item, int position){
struct node *p,*newnode;
//node creation.
newnode = (struct node *)malloc(sizeof(struct node));
if (!newnode)
{
printf("Memory Error.\n");
return;
}
newnode->next = NULL;
newnode->data = item;
p = *ptrhead;
// Creates initial node
if (!(p->data))
{
p = newnode;
}
// insertion at beginning
if (position==1)
{
newnode->next = p;
p = newnode;
free(newnode);
}
// insertionn at middle or end.
else
{
int i=1;
while(p->next!=NULL && i<position-1){
p=p->next;
i++;
}
newnode->next = p->next;
p->next = newnode;
}
*ptrhead = p;
};
// Display Linked list
void display(struct node *head){
if (head)
{
do{
printf("%d\n", head->data);
head = head->next;
}while(head->next);
}
};
I will add functions for deletion and other operations later. Right now , I just want to insert and display fns to work . But output comes as infinitely running loop with wrong values. I cannot figure out what's wrong in my code , please help ?
Thanks in advance.
Not sure why somebody would be writing this type of C today, looks like maybe I'm doing your homework for you... In any case, you asked to fix your code, not rewrite it, so here's the minimum set of changes.
head should be initialized to NULL.
if (!(p->data)) is not right. That if statement should just be:
// Creates initial node
if (!p)
{
*ptrhead = newnode;
return;
}
Remove free(newnode);.
The insert at middle/end code could be
int i = 1;
struct node *n = p;
while (n->next != NULL && i<position - 1){
n = n->next;
i++;
}
newnode->next = n->next;
n->next = newnode;
The final insert function:
void Insert(struct node **ptrhead, int item, int position)
{
struct node *p, *newnode;
//node creation.
newnode = (struct node *)malloc(sizeof(struct node));
if (!newnode)
{
printf("Memory Error.\n");
return;
}
newnode->next = NULL;
newnode->data = item;
p = *ptrhead;
// Creates initial node
if (!p)
{
*ptrhead = newnode;
return;
}
// insertion at beginning
if (position == 1)
{
newnode->next = p;
p = newnode;
}
// insertionn at middle or end.
else
{
int i = 1;
struct node *n = p;
while (n->next != NULL && i<position - 1){
n = n->next;
i++;
}
newnode->next = n->next;
n->next = newnode;
}
*ptrhead = p;
}
Your print function isn't quite right, just make it:
// Display Linked list
void display(struct node *head)
{
while (head)
{
printf("%d\n", head->data);
head = head->next;
}
}

Why is it not displaying the output? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm trying to write a program where I create new nodes and insert items in there.
My problem is when I want to display the items in all the nodes it's not showing it.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define NULL 0
struct node{
int item;
struct node *next;
}lol;
struct node *head = NULL;
void insertfirst(int ele);
void insertnext(int ele);
void displayelement();
int main()
{
clrscr();
int ele,choice;
printf("Enter element in first node:");
scanf("%d",&ele);
do{
printf("Please select any of the other options\n1.Add element to new node\n2.Display elements\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Enter element in node:");
scanf("%d",&ele);
insertnext(ele);
break;
case 2:
displayelement();
break;
default:
break;
}
getch();
clrscr();
displayelement();
}while(choice < 3);
getch();
return 0;
}
void insertfirst(int ele)
{
struct node *p;
p = (struct node*)malloc(sizeof(struct node));
p -> item = ele;
p -> next = head;
head = p;
}
void insertnext(int ele)
{
struct node *temp;
struct node *p;
temp = head;
p = (struct node*)malloc(sizeof(struct node));
temp = head;
p->item = ele;
p->next = temp ->next;
temp -> next = p;
}
void displayelement()
{
struct node *temp;
temp = head;
printf("\n The nodes are");
while(temp!=NULL)
{
printf("%d",temp -> item);
temp = temp -> next;
}
}
The program seemed to have worked when i did it directly without using switch case
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define NULL 0
struct node{
int item;
struct node *next;
}lol;
struct node *head = NULL;
void insertfirst(int ele);
void insertnext(int ele);
void displayelement();
int main()
{
clrscr();
int ele;
printf("Enter element in first node:");
scanf("%d",&ele);
insertfirst(ele);
insertnext(ele);
displayelement();
getch();
return 0;
}
void insertfirst(int ele)
{
struct node *p;
p = (struct node*)malloc(sizeof(struct node));
p -> item = ele;
p -> next = head;
head = p;
}
void insertnext(int ele)
{
struct node *temp;
struct node *p;
temp = head;
p = (struct node*)malloc(sizeof(struct node));
temp = head;
p->item = ele;
p->next = temp ->next;
temp -> next = p;
}
void displayelement()
{
struct node *temp;
temp = head;
printf("\n The nodes are");
while(temp!=NULL)
{
printf("%d",temp -> item);
temp = temp -> next;
}
}
You forgot to call insertfirst from the new code leading to undefined behavior in insertnext as you dereference a NULL pointer.
Fix the problem by adding
insertfirst(ele);
after
printf("Enter element in first node:");
scanf("%d",&ele);
That looks better:
void insertfirst(int ele)
{
head = (struct node*)malloc(sizeof(struct node));
head->item = ele;
head->next = head;
}
void insertnext(int ele)
{
struct node *p;
p = (struct node*)malloc(sizeof(struct node));
p->item = ele;
p->next = head->next;
head->next = p;
}

Values added wont save in the node

Please help values wont save once added into the list and nothing is printed as a result
#include <stdio.h>
#include <stdlib.h>
struct node{
char first[30];
char last[30];
char address[100];
char postal[6];
char number[10];
struct node* next;
};
typedef struct node node;
void print(node* root);
node* add(node* root);
void addinfo(node* root);
int main(){
node* root=NULL;
root=add(root);
print(root);
return 0;
}
Its supposed to add a new node at the end of the list then add values
node* add(node* root){
if(root==NULL){
root=(node*) malloc(sizeof(node));
addinfo(root);
root->next=NULL;
return root;
}
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=(node*)malloc(sizeof(node));
addinfo(temp);
temp->next=NULL;
return root;
}
void print(node* root){
node* temp=root;
while(temp!=NULL){
printf("First Name: %s\n",temp->first);
printf("Last Name:%s\n",temp->last);
printf("Address:%s\n",temp->address);
printf("Postal%s\n",temp->postal);
printf("Phone Number:%s\n",temp->number);
temp=temp->next;
}
}
If I print in the function, the values print normally but once this functions ends all the values are gone.
void addinfo(node* root){
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=malloc(sizeof(node));
printf("Please enter a name:");
gets(temp->first);
printf("Please enter a last name:");
gets(temp->last);
printf("Please enter an address:");
gets(temp->address);
printf("Please enter a postal code:");
gets(temp->postal);
printf("Please enter a phone number:");
gets(temp->number);
}
The simplest way of implementing what you want is keeping a pointer to the last item of a list:
typedef struct list {
node *first;
node *last;
} list;
Then you initialize a list with
list alist = { NULL, NULL };
and add items as follows:
void addNewNode(list *plist, node *pnode)
{
pnode->next = NULL;
if( plist->first == NULL)
plist->first = pnode;
else
plist->last->next = pnode;
plist->last = pnode;
}
fill the list:
while(there_is_something_to_read())
{
node *newnode = malloc(sizeof(node));
addInfo(newnode);
addNewNode(&alist, newnode);
}
note however, addInfo() should do just what its name says: add info to the node; no list manipulation:
void addinfo(node* pnode){
printf("Please enter a name:");
gets(pnode->first);
// .........
printf("Please enter a phone number:");
gets(pnode->number);
}
print it:
node *pnode;
for(pnode = alist.first; pnode != NULL; pnode = pnode->next)
printNode(pnode);
with
void printNode(node *pnode)
{
printf( "first name: %s\n", pnode->first);
//...
printf( "phone: %s\n", pnode->number);
printf( "\n");
}
The problem is in this code:
void addinfo(node* root){
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=malloc(sizeof(node));
You carefully traverse the entire list until temp is NULL (which could be achieved more swiftly by writing temp = NULL; and then you overwrite the NULL with newly allocated memory, but don't hook the new node into the list.
This function cannot be used on an empty list. It can be revised to work on a non-empty list:
void addinfo(node *root)
{
if (root == NULL)
return; // Report error?
node *temp = root;
while (temp->next != NULL)
temp = temp->next;
temp->next = malloc(sizeof(node));
if (temp->next == NULL)
return; // Report error?
temp = temp->next;
temp->next = NULL;
…other code as before…
}

improvement in my linklist program

Here is a program it is working
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next, *prev;
};
struct node *root = NULL;
void push(int);
void pop(void);
struct node *create_node(int);
void travel(void);
int main()
{
int i, j, choice, count;
printf("enter choice\n");
scanf("%d", &choice);
count = 0;
while (choice == 1) {
printf("enter a data element");
scanf("%d", &j);
if (count == 0) {
root = (struct node *)malloc(sizeof(struct node));
root->next = NULL;
root->data = j;
} else
push(j);
count++;
printf("enter choice\n");
scanf("%d", &choice);
}
printf("the link list is \n");
//travel function to be created
travel();
}
void push(int data)
{
struct node *t1;
t1 = root;
while (t1->next != NULL) {
t1 = t1->next;
}
t1->next = create_node(data);
}
void pop()
{
}
void travel(void)
{
struct node *t1;
t1 = root;
while (t1->next != NULL) {
printf("%d ", t1->data);
t1 = t1->next;
}
printf("%d ", t1->data);
}
struct node *create_node(int data)
{
struct node *p = (struct node *)malloc(sizeof(struct node));
p->data = data;
p->next = NULL;
p->prev = NULL;
return p;
}
the above program is fully working,I have used a global pointer root.
My problem is if I do not want to use a global pointer root here then how do I maintain
that list because each time I will have to return the root of list in my push pop functions
is there any other way to achieve the same?
The simplest way to achieve this is to pass a pointer to the root node pointer to each of your functions:
void push(struct node **root, int data) { ... }
void pop(struct node **root) { ... }
void travel(struct node *root) { ... }
So, in your main function you might declare a local variable to hold the root pointer:
struct node *root = NULL;
and then when you call push, for example, you pass the address of the root poiner:
push(&root, data);
I strongly recommend that you fix your push and travel functions so that they are robust to the root pointer being NULL. This was discussed in a previous question of yours and you should heed the advice.
If you did that then you could get rid of the test for count being zero and the associated special case code. You would then replace this:
if (count == 0) {
root = (struct node *)malloc(sizeof(struct node));
root->next = NULL;
root->data = j;
} else
push(&root, j);
with this:
push(&root, j);
To drive home the message, your new push would look like this:
void push(struct node **root, int data)
{
if (*root == NULL)
*root = create_node(data);
else
{
struct node *last = *root;
while (last->next != NULL) {
last = last->next;
}
last->next = create_node(data);
}
}
You would need to modify travel also to include a check for the root node being NULL. I will leave that as an exercise for you.
Maintaining both head and tail pointers could be a better approach since it would avoid so many list traversals.

inserting an element in a linked list

Considering a linked list containing five elements.
1,2,3,4,5 a no '7' is to be inserted after two. we will have an head pointing to the first element of the linked list and ptr at the last. while inserting an element before 3 we will loop through the linked list starting from head to last and we will introduce another pointer(prev) to hold the previous pointers address.ptr will point to the current node and if a matching data is found(3) then we have to include the new node between 2 and 3.
We can do it as we have previous pointer.How to do it without using a previous pointer.
EDITED:
#include<stdio.h>
#include<stdlib.h>
struct list
{
int data;
struct list* link;
};
struct list *head=NULL;
struct list *tail=NULL;
void createList(int value);
void displayList(struct list* head_node);
void insertNewNode();
int value;
int main()
{
int i;
for(i=0;i<5;i++)
{
printf("\nEnter the data to be added into the list:\n");
scanf("%d",&value);
createList(value);
}
printf("\nCreated Linked list is\n");
//displayList(head);
printf("\nInsert a node\n");
insertNewNode();
displayList(head);
return 0;
}
void insertNewNode()
{
int val;
struct list* ptr=NULL,*new_node,*prev=NULL;
new_node = (struct list*)malloc(sizeof(struct list));
printf("Enter the data to be inserted!");
scanf("%d",&val);
for(ptr=head;ptr;ptr=ptr->link)
{
if(ptr->data == 3)
{
printf("Found");
new_node->data = val;
prev->link=new_node;
new_node->link = ptr;
}
prev = ptr;
}
}
void createList(int value)
{
struct list *newNode;
newNode = (struct list*)malloc(sizeof(struct list));
//tail = (struct list*)malloc(sizeof(struct list));
newNode->data = value;
if(head == NULL)
{
head = newNode;
}
else
{
tail->link = newNode;
}
tail = newNode;
tail->link = NULL;
}
void displayList(struct list *head_node)
{
struct list *i;
for(i=head;i;i=i->link)
{
printf("%d",i->data);
printf(" ");
}
printf("\n");
}
void insertNewNode()
{
int val;
struct list* ptr=NULL,*new_node;
new_node = (struct list*)malloc(sizeof(struct list));
printf("Enter the data to be inserted!");
scanf("%d",&val);
for(ptr=head;ptr;ptr=ptr->link)
{
if(ptr->data == 2)
{
printf("Found");
new_node->data = val;
new_node->link = ptr->link;
ptr->link = new_node;
}
}
}
Update:
This is probably what you want:
void insertNewNode()
{
int val;
struct list* ptr=NULL,*new_node;
new_node = (struct list*)malloc(sizeof(struct list));
printf("Enter the data to be inserted!");
scanf("%d",&val);
for(ptr=head;ptr->link;ptr=ptr->link)
{
if(ptr->link->data == 3)
{
printf("Found");
new_node->data = val;
new_node->link = ptr->link;
ptr->link = new_node;
}
}
}
Here:
if(ptr->link->data == 3)
you simply look ahead to check if next node has value that you need.
Let's call curr the pointer at the current element, next the pointer at the next element, and value the number stored.
Traverse the list until curr.value == 2, now just create a new_node with new_node.value = 7 and set new_node.next = curr.next and curr.next = new_node

Resources