I'm trying to write a function that inserts node at the end of the list.
The problem is that the pointer of the last node of the list doesn't point to NULL and if I show the list I get an error from the system.
struct node{
int value;
struct node *next;
};
struct node *AddToList (struct node *list, int n);
int main()
{
struct node *node;
node = AddToList(node, 30);
node = AddToList(node, 20);
node = AddToList(node, 10);
showlist(node);
return 0;
}
struct node *AddToList (struct node *list, int n){
struct node *new_node;
new_node=malloc(sizeof(struct node));
new_node->value=n;
new_node->next=list;
return new_node;
};
Yes that's because first node that you insert - it's next is not having the value NULL.
struct node *node = NULL; //<------
node = AddToList(node, 30);
node = AddToList(node, 20);
node = AddToList(node, 10);
showlist(node);
This will solve the problem. Now as a result of doing this - the very first time you insert the node, it's next will be assigned the value NULL. Because for the first call to AddToList the list is NULL.
The way you did it - node was containing some indeterminate value (garbage value)(node is a variable with automatic storage duration) and then this is added as link to the first node. This is of no practical use because now you can't traverse the list thinking that you will find a NULL value which is when you should stop.
From standard chapter ยง6.7.9
If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate.
You should check the return value of malloc. In case it fails - you should handle that case. And free the dynamically allocated memory when you are done working with it.
Also not sure how did you try to show the list, but if it is with the assumption that last node will point to NULL then started looping over it - then you have earned a Undefined behavior in your code.
'm trying to write a function that inserts node at the end of the
list.
This function
struct node *AddToList (struct node *list, int n){
struct node *new_node;
new_node=malloc(sizeof(struct node));
new_node->value=n;
new_node->next=list;
return new_node;
};
does not insert a node at the end of the list. It inserts a node at the beginning of the list before the head node.
The function that inserts a node at the end of the list can look the following way.
int AddToList ( struct node **list, int n )
{
struct node *new_node = malloc( sizeof( struct node ) );
int success = new_node != NULL;
if ( success )
{
new_node->value = n;
new_node->next = NULL;
while ( *list != NULL ) list = &( *list )->next;
*list = new_node;
}
return success;
}
And the function can be called like
struct node *head = NULL;
AddToList( &head, 10);
AddToList( &head, 20);
AddToList( &head, 30);
if you want that the order of the values of the list would be 10, 20, 30.
The problem is that the pointer of the last node of the list doesn't
point to NULL
Because new nodes are inserted before the first node that was not initialized
struct node *node;
and hence has an indeterminate value the last node in the list does not point to NULL.
You have to set the initial pointer to NULL.
struct node *node = NULL;
Take into account that according to the C Standard the function main without parameters shall be declared like
int main( void )
when the user wants to add node at the last first check if it is empty list if so means add the new node as head node.if the list is not empty travese the list and find out the last node by checking tp->next=NULL then store the address of new node in tp->next and make the new node's next field with NULL.the following program show the concept clearly
#include<stdio.h>
#include<malloc.h>
int item,count,pos;
struct node
{
int info;
struct node *next;
}*head,*tp;
void traversal()
{
if(head==NULL)
printf("\n List is empty");
else
{
tp=head;
while(tp->next!=NULL)
{
printf("\n%d",tp->info);
tp=tp->next;
}
printf("\n%d",tp->info);
}
}
void insertlast()
{
struct node *temp;
temp=(struct node*) malloc(sizeof(temp));
printf("\nEnter the element:");
scanf("%d",&item);
temp->info=item;
temp->next=NULL;
if(head==NULL)
head=temp;
else
{
tp=head;
while(tp->next!=NULL)
{
tp=tp->next;
}
tp->next=temp;
}
}
int main()
{
printf("\n\t\t**********SINGLY LINKED LIST********");
printf("\n\t------------------------------------------------------");
printf("\n\tInsertion last:");
printf("\n\t---------------------");
insertlast();
traversal();
printf("\n\tInsertion last:");
printf("\n\t---------------------");
insertlast();
traversal();
printf("\n\n\tInsertion last:");
printf("\n\t---------------------");
insertlast();
traversal();
printf("\n\n\tInsertion last:");
printf("\n\t---------------------");
insertlast();
traversal();
return 0;
}
Output
**********SINGLY LINKED LIST********
------------------------------------------------------
Insertion last:
---------------------
Enter the element:12
12
Insertion last:
---------------------
Enter the element:13
12
13
Insertion last:
---------------------
Enter the element:14
12
13
14
Insertion last:
---------------------
Enter the element:15
12
13
14
15
hope that u understand.Thank you
Related
In this I am trying to insert values in empty linked list initially and then adding element after that .
function insert is inserting element in linked list .
display function is displaying linked list .
so i am getting output as first insertion only .
#include<stdio.h>
#include<stdlib.h>
struct node
{
int value;
struct node *next;
}*first = NULL;
void insert(struct node *ptr,int n ){
struct node* t;
t=(struct node* )malloc(sizeof(struct node ));
t->value=n;
if(first==NULL){
t->next=first;
first=t;
return;
}
else{
ptr=first;
while(ptr!=NULL){
ptr=ptr->next;
}
t->next=ptr;
t->value=n;
ptr=t;
}
}
void display(struct node *f){
while(f!=NULL){
printf("%d",f->value);
f=f->next;
}
}
int main(){
insert(first,5);
insert(first,20);
insert(first,32);
insert(first,66);
insert(first,689);
display(first);
return 0;
}
First off, you're reassigning ptr before making use of its original value, and you're accessing start in the function directly anyway, so passing it as a function parameter is not needed.
Look more carefully at your appending code:
ptr=first;
while(ptr!=NULL){
ptr=ptr->next;
}
// you only reach here when ptr is NULL!
t->next=ptr; // sets next to NULL
t->value=n; // you've already set the value after you malloc'd the node
ptr=t; // this line has no overall affect. You're setting the local pointer "ptr" to point to something then it goes out of scope.
In short, you've got your pointers the wrong way round. What you instead want to be doing here is getting up to the last element and then setting its next to the new node:
struct node* ptr=first;
while(ptr->next!=NULL){
ptr=ptr->next;
}
// Now when we reach here, "ptr" is the last element in the list
ptr->next = t;
However, looping the entire list for every iteration is fairly inefficient, you could instead store a node* last as well as the first to avoid the loop:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int value;
struct node *next;
} *first = NULL, *last = NULL;
void insert(int n){
struct node* t;
t = (struct node*)malloc(sizeof(struct node));
t->value = n;
t->next = NULL
if (first == NULL) { // last == NULL too
first = last = t;
return;
}
last->next = t;
last = t;
}
I am learning C and I've come up with a conceptual question about pointers.
Here is a simple code to push (add to the beginning) an int to a linked list in C.
The following code works:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *next;
} node_t;
void push(node_t **head, int val) {
// head is a pointer to the pointer of the first node_t
node_t *new_node; // new pointer to a node
new_node = (node_t *)malloc(sizeof(node_t));
new_node->val = val;
new_node->next = *head;
*head = new_node;
}
int main() {
// creating the first node
node_t *head;
head = (node_t *)malloc(sizeof(node_t));
head->val = 2;
head->next = NULL;
// pushing a value
push(&head, 1); // the '&' is important
return 0;
}
As you notice, we have to pass &head as a parameter. So I though changing the function so I could pass head instead. Here's the modified function :
void push(node_t *head, int val) {
node_t **p_head;
p_head = &head; // p_head is a pointer to the pointer of the first node_t
node_t *new_node; // pointer to a new node
new_node = (node_t *)malloc(sizeof(node_t));
new_node->val = val;
new_node->next = *p_head;
*p_head = new_node;
}
Why does this version won't work ?
Thanks in advance.
You should be able to pass along the structure's pointer for the creation of another structure in a linked list. I would suggest looking at the linked list structure in a slightly different way.
Usually, in the creation of a linked list, whenever a new list item (aka structure in your case) is created, the "next node structure" pointer is set to null and the previous linked list member has its "next node structure" pointer updated to the pointer of the newly created structure. Making some revisions to your program I store some additional information in your structure and produce a linked list of ten members. Following is the revised code.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int val;
struct node *previous; /* Added this to use with the passed node pointer */
struct node *next;
} node_t;
node_t * push(node_t *nd, int val) /* Return the pointer of the newly created node */
{
node_t *new_node; // New pointer to a node
new_node = (node_t *)malloc(sizeof(node_t));
new_node->val = val;
new_node->previous = nd;
new_node->next = NULL;
return new_node;
}
int main()
{
node_t *work; // Pointer work variable for building a linked list of nodes
node_t *head;
head = (node_t *)malloc(sizeof(node_t));
head->val = 2; /* This value will get adjusted to provide unique values */
head->previous = NULL;
// Create a set of ten nodes.
work = head;
for (int i = 0; i < 10; i++)
{
work->next = push(work, (2 * i + i + 12));
work = work->next; /* Links this node to the newly created node. */
}
// Now travel down the chain and print out the pertinent statistics of the nodes.
work = head;
while (1)
{
printf("This node's values are: this->%p value->%d previous->%p next->%p.\n", work, work->val, work->previous, work->next);
if (work->next == NULL) /* We have reached the end of the list */
break;
work = work->next;
}
return 0;
}
When I ran this program, I received the following output on my terminal.
This node's values are: this->0x55bfd6edc2a0 value->2 previous->(nil) next->0x55bfd6edc2c0.
This node's values are: this->0x55bfd6edc2c0 value->12 previous->0x55bfd6edc2a0 next->0x55bfd6edc2e0.
This node's values are: this->0x55bfd6edc2e0 value->15 previous->0x55bfd6edc2c0 next->0x55bfd6edc300.
This node's values are: this->0x55bfd6edc300 value->18 previous->0x55bfd6edc2e0 next->0x55bfd6edc320.
This node's values are: this->0x55bfd6edc320 value->21 previous->0x55bfd6edc300 next->0x55bfd6edc340.
This node's values are: this->0x55bfd6edc340 value->24 previous->0x55bfd6edc320 next->0x55bfd6edc360.
This node's values are: this->0x55bfd6edc360 value->27 previous->0x55bfd6edc340 next->0x55bfd6edc380.
This node's values are: this->0x55bfd6edc380 value->30 previous->0x55bfd6edc360 next->0x55bfd6edc3a0.
This node's values are: this->0x55bfd6edc3a0 value->33 previous->0x55bfd6edc380 next->0x55bfd6edc3c0.
This node's values are: this->0x55bfd6edc3c0 value->36 previous->0x55bfd6edc3a0 next->0x55bfd6edc3e0.
This node's values are: this->0x55bfd6edc3e0 value->39 previous->0x55bfd6edc3c0 next->(nil).
Hopefully, this might give you some food for thought on pointer usage as it pertains to linked lists. Also, since the program is using "malloc" it usually is a good idea to have some cleanup in the program to make sure the memory is freed up (e.g. use the "free()" function).
Hope that helps.
Regards.
Actually in an interview i was asked to write a code through which every node in a binary search tree is having a extra pointer namely "next" we have to connect this pointer of every node to its pre order successor ,can any one suggest me the code as i was not able to do so. the tree nodes has above structure :-
struct node {
int data ;
struct node *left,*right;
struct node *next; //this pointer should point to pre order successor
};
thank you .
Cracked the the solution thanks to you guys ,below is the whole code written in c :-
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left,*right,*next;
};
struct node* getNode(int data)
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
temp->left=temp->right=NULL;
temp->data=data;
return temp;
}
void insert(struct node**root,int data)
{
if(!*root)
{
*root=(struct node*)malloc(sizeof(struct node));
(*root)->left=(*root)->right=NULL;
(*root)->data=data;
}
else if(data<(*root)->data)
insert(&((*root)->left),data);
else if(data>(*root)->data)
insert(&((*root)->right),data);
}
struct node* preorderSuccessor(struct node* root,struct node* p)
{
int top,i;
struct node *arr[20];
if(!root || !p)
return NULL;
if(p->left)
return p->left;
if(p->right)
return p->right;
top=-1;
while(root->data!=p->data)
{
arr[++top]=root;
if(p->data<root->data)
root=root->left;
else
root=root->right;
}
for(i=top;i>=0;i--)
{
if(arr[i]->right)
{
if(p!=arr[i]->right)
return arr[i]->right;
}
p=arr[i];
}
return NULL;
}
void connect(struct node* parent,struct node *r)
{
if(r)
{ connect(parent ,r->left);
r->next = preorderSuccessor(parent,r);
connect(parent,r->right);
}
}
int main()
{
struct node* root=NULL,*temp=NULL;
int arr[]={10,11,2,3,9,8,4,5},size,i;
size=sizeof(arr)/sizeof(arr[0]);
for(i=0;i<size;i++)
insert(&root,arr[i]);
connect(root,root);
struct node *ptr = root;
while(ptr){
// -1 is printed if there is no successor
printf("Next of %d is %d \n", ptr->data, ptr->next? ptr->next->data: -1);
ptr = ptr->next;
}
return 0;
}
As Eugene said: So traverse the tree with preorder traversal and connect. To do that, you need to know which node, if any, you visited last.
You can do that with the usual recursive approach by passing a reference to the previous node. This must be the address of a variable that is valid throughout the recursion, because the previous node is not necessarily closer to the root. You could use a global variable, but a variable created in a wrapper function may be better:
void connect_r(struct node *node, struct node **whence)
{
if (node) {
if (*whence) (*whence)->next = node;
*whence = node;
connect_r(node->left, whence);
connect_r(node->right, whence);
}
}
void connect(struct node *head)
{
struct node *p = NULL;
connect_r(head, &p);
if (p) p->next = NULL;
}
The pointer p in connect, whose address is passed to the recursive function connect_r holds the node whose next pointer should be updated next. The update doesn't happen on the first visited node. and the next member of the last visited node must explicitly be set to NULL after the recursion.
Alternatively, you can connect the nodes iteratively by using a stack:
void connect(struct node *head)
{
struct node *p = NULL;
struct node **prev = &p;
struct node *stack[32]; // To do: Prevent overflow
size_t nstack = 0;
if (head) stack[nstack++] = head;
while (nstack) {
struct node *node = stack[--nstack];
*prev = node;
prev = &node->next;
if (node->right) stack[nstack++] = node->right;
if (node->left) stack[nstack++] = node->left;
}
*prev = NULL;
}
The connected next pointers are a snapshot of the current tree. Insertions, deletions and rearrangements of nodes will render the next chain invalid. (But it can be made valid again by calling connect provided that the tree's left and right links are consistent.)
I want to make a double linked list and I have a problem with accessing fields in the struct. This is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int val;
struct node * next;
struct node * prev;
}node;
void insert(int val, node **head)
{
node * temp= *head;
node * temp2=(node *)malloc(sizeof(node));
node * temp3=(node *)malloc(sizeof(node));
temp2->val=val;
temp2->prev=NULL;
temp2->next=*head;
*head=temp2;
temp2->next->prev=temp2;
}
void print(node* head)
{
node* temp=head;
while(temp!=NULL)
{
printf("%d ", temp->val);
temp=temp->next;
}
}
int main()
{ node * head=NULL;
insert(1, &head);
insert(2, &head);
print(head);
return 0;
}
I get a crash at temp2->next->prev, and I don't understand why. Am I not allowed to access the prev field of the temp2->next node? I tried writing (temp2->next)->prev but also doesn't work. Is there any way that I cant make that work?
When you insert the first node, *head, and therefore temp->next, is NULL. Check that case:
void insert(int val, node **head)
{
node *temp= malloc(sizeof(*temp));
temp->val = val;
temp->prev = NULL;
temp->next = *head;
*head = temp;
if (temp->next) temp->next->prev = temp;
}
(I've removed the unused variables and lost the cast on malloc.)
A doubly linked list should probably have a tail, too. In that case, update the tail when you append an item at the head of an empty list.
try this:
void insert(int val, node **head)
{
if(*head == NULL){
node * temp2=(node *)malloc(sizeof(node));
temp2->val=val;
*head = temp2;
}
else{
node * temp= *head;
node * temp2=(node *)malloc(sizeof(node));
temp2->val=val;
temp2->prev=NULL;
temp2->next=temp;
temp->prev = temp2;
}
}
Most likely head was not initialized
As I have understood you always insert a new node before the head though in double linked list you have to add new nodes usually at the tail of the list. As a double linked list usually have two sides then there is a sense to define two functions: push_front and push_back. Your function insert corresponds to function push_front.
Nevertheless function insert could look the following way
void insert( int val, node **head )
{
node *temp = ( node * )malloc( sizeof( node ) );
temp->val = val;
temp->prev = NULL;
temp->next = *head;
if ( *head ) ( *head )->prev = temp;
*head = temp;
}
It would be better if you would define one more structure named as for example List (or whatever) and that could be defined as
struct List
{
node *head;
node *tail;
};
Also you could add one more data member - a count of the nodes in the list, For example
struct List
{
node *head;
node *tail;
size_t count;
};
Also do not forget to write a function that would delete all nodes of the list when it is not needed any more.
typedef struct LIST{
int count = 0;
}LIST;
typedef struct NODE{
int data;
struct NODE *link;
}NODE;
int main() {
NODE *p1, *p2, *p3;
p1 = (NODE*)malloc(sizeof(NODE));
p1->link = NULL;
p2 = (NODE*)malloc(sizeof(NODE));
p2->data = 20;
p2->link = NULL;
p1->link = p2;
I want to make add NODE function and list to control NODE.
Give me some answer to solve this problem.
you should define head in the list.
node * head;
Insert function as follows, to insert value in ascending order.
void insert(int val)
{
node * nd = new node();
nd->val = val;
if(head == NULL)
head = nd;
else
{
if(val <= head->val)
{
nd->next = head;
head = nd;
}
else
{
node * itr = head;
while(itr->next != NULL && itr->next->val <= val)
itr = itr->next;
nd->next = itr->next;
itr->next = nd;
}
}
}
First you probably want to add to your LIST struct a field "NODE *first", which points to NULL initially, and then will point to the first element of your list.
Then what does you add function should do? Add to the beginning or the end of the list?
If at the beginning: allocate a NODE, set its link pointer to the first element of your list and say that the first element of the list is now the node that you just allocated.
Try to give variable according to their work, so that it is easy to understand.
struct node
{
int val;
struct node* next;
};
void insert(struct node** head_ref, int data)
{
struct node* new_node = (struct node*)malloc(sizeof(struct node));
new_node->val = data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
int main()
{
struct node* head = NULL;
insert(&head,1);
insert(&head,2);
return 0;
}
Note that : Insert function will always add the value at front.
Try to write function for particular task.
I'll avoid giving you the entire answer in C code since it's in general better to "teach a man to fish".
I would suggest that you add a NODE * member to your LIST class to store the header node of your linked list.
The addNode that adds a node to the next node should look like this:
void addNode (LIST* list, NODE * penultNode, int newData);
// list: Address to the linked list info object
// penultNode: Address to the node after which you want to add a new node.
// Should be NULL if your linkedlist is empty
// newData: Data in the new node that you wanna add
Inside this function, your actions will depend on whether penultNode is NULL or not. If it is not null, your job is simple. You just allocate a new NODE object and set the pointer of penultNode->next to the new object. If it is NULL, that means that no node exists in the list yet. In this case, you will need to set the pointer of list->headerNode to the new NODE object.