Singly linked list in c - c

below is my code for singly linked list in c. Can anyone help me with this?
this is my main c file:
#include <stdio.h>
#include <stdlib.h>
#include "myclib.c"
struct mydata
{
int num;
char name;
struct mydata *next;
};
int main()
{
struct mydata *head, *newnode, *temp;
head = (struct mydata*)malloc(sizeof(struct mydata));
newnode = (struct mydata*)malloc(sizeof(struct mydata));
temp = (struct mydata*)malloc(sizeof(struct mydata));
head -> num = 123;
head -> name = 'k';
head -> next = NULL;
newnode -> num = 456;
newnode -> name = 'd';
newnode -> next = NULL;
printf("before.app.head = %p\n",head);
printf("before.app.newnode = %p\n",newnode);
printf("before.app.head->next = %p\n",head -> next);
printf("before.app.newnode->next = %p\n",newnode -> next);
head = (struct mydata*)addNodeAtHead(head, newnode, (newnode -> next));
printf("after.app.head = %p\n",head);
printf("after.app.newnode = %p\n",newnode);
printf("after.app.head->next = %p\n",head -> next);
printf("after.app.node->next = %p\n",newnode -> next);
temp = head;
while(temp != NULL)
{
printf("num : %d\n",temp -> num);
printf("name : %c\n",temp -> name);
temp = temp -> next;
}
free(temp);
free(head);
return 0;
}
this is myclib.c file:
#include <stdio.h>
void * addNodeAtHead(void *head, void *node, void *nodenext)
{
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
printf("before.nodenext = %p\n",nodenext);
nodenext = head;
head = node;
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
printf("after.nodenext = %p\n\n",nodenext);
return head;
}
i am trying to add newnode in front of head and than changing head pointer to newnode.

#include <stdio.h>
#include <stdlib.h>
//#include "myclib.c"
struct mydata
{
int num;
char name;
struct mydata *next;
};
struct mydata* addNodeAtHead(struct mydata* head, struct mydata* node)
{
#ifdef DEBUG
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
// printf("before.nodenext = %p\n",nodenext);
#endif
if(node){
node->next = head;
head = node;
}
#ifdef DEBUG
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
// printf("after.nodenext = %p\n\n",nodenext);
#endif
return head;
}
int main()
{
struct mydata *head, *newnode, *temp;
head = (struct mydata*)malloc(sizeof(struct mydata));
newnode = (struct mydata*)malloc(sizeof(struct mydata));
//temp = (struct mydata*)malloc(sizeof(struct mydata));//unused and rewrite to other pointer
head -> num = 123;
head -> name = 'k';
head -> next = NULL;
newnode -> num = 456;
newnode -> name = 'd';
newnode -> next = NULL;
#ifdef DEBUG
printf("before.app.head = %p\n",head);
printf("before.app.newnode = %p\n",newnode);
printf("before.app.head->next = %p\n",head -> next);
printf("before.app.newnode->next = %p\n",newnode -> next);
#endif
head = (struct mydata*)addNodeAtHead(head, newnode);
#ifdef DEBUG
printf("after.app.head = %p\n",head);
printf("after.app.newnode = %p\n",newnode);
printf("after.app.head->next = %p\n",head -> next);
printf("after.app.node->next = %p\n",newnode -> next);
#endif
temp = head;
while(temp != NULL)
{
printf("num : %d\n",temp -> num);
printf("name : %c\n",temp -> name);
temp = temp -> next;
}
/*
free(temp);//NULL
free(newnode);//...
free(head);//already changed
*/
temp=head;
while(temp != NULL){
struct mydata *prev = temp;
temp=temp->next;
free(prev);
}
return 0;
}

When you are passing (newnode -> next) to the function addNodeAtHead. The value of (newnode -> next) is copied to the node variable in the function. And you are updating that node variable with new value head. After the execution of the function node variable get destroyed and has no relation with (newnode -> next). And so (newnode -> next) remains unchanged.
To over come it, just change your addNodeAtHead like bellow:
void * addNodeAtHead(void *head, void *node)
{
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
((mydata *)node)-> next = (mydata *) head;
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
return node;
}
And call it simply like:
head = (struct mydata*)addNodeAtHead(head, newnode);
And Everything should be okay now.

You need to set the next pointer on the added node to point to the original head node.
I changed the signature of addNodeAtHead: You should not pass void * when you are alyway passing pointers of the type mydata *. I also change the variable names to be more clear (IMO) about their purpose
mydata * addNodeAtHead(mydata * original_head, mydata * new_node)
{
new_node -> next = original_head;
return new_node; // new_node is now the head of the list!
}

**PROGRAM ON SINGLY LINKER LIST ( CREATION AND TRAVERSING WITH COMMENTS )**
#include<stdio.h> //Header file for input and output operations.
#include<conio.h>
struct node // structure declaration .
{
int info; // stores information.
struct node *link; // stores the address of next link.
};
struct node *first; // used to point to the first node.
void create(); // function call |NOTE| This line is optional.
void traverse(); // function call |NOTE| This line is optional.
int main() // main function.
{
create(); // function call for creation.
traverse(); // function call for traversing i.e nothing but display.
return 0;
}
void create() // declaration of create function , creation of nodes.
{
char ch; // variable to take an input from the user for decision.
struct node *ptr,*cpt; // these are used to create a node and referred to as
//previous pointer and current pointer.
ptr=(struct node*)malloc(sizeof(struct node)); //dynamic declaration
printf("Enter data into the first node \n");
scanf("%d",&ptr->info); // taking the input from the user.
first=ptr; //assigning the information taken from previous pointer to first for
//future identification.
do // loop which continuously generates and links new nodes to previous nodes.
{
cpt=(struct node*)malloc(sizeof(struct node)); //dynamic declaration of current
//pointer.
printf("Enter the data for another node \n");
scanf("%d",&cpt->info); // getting input from the user of next node
// information.
ptr->link=cpt; // linking the previous pointer to the new pointer.
ptr=cpt; // transferring the previous node information to the current node
//i.e previous pointer to the current pointer.
printf("Do you want to create another node <Y/N>:\n\n");
ch=getch(); // getting the users decision.
}
while(ch=='y'); // checking the users decision.
ptr->link=NULL; // assigning the previous pointer link to null;
}
void traverse() // function declaration of display or traversing.
{
int count=1; // counting variable for naming the nodes.
struct node *ptr; // pointer variable used for traversing.
ptr=first; // assigning ptr to the first for starting traversing from the
//first node.
printf("TRAVERSING OF A LINKED LIST \n");
while(ptr!=NULL) // checking whether the ptr is null or not, And if not
//executes the statements written in the body.
{
printf("The data stored in node %d is:%d \n",count,ptr->info); //prints the
// node id and information present in the node.
ptr=ptr->link; // This statement is used to traverse to the next node.
count++; // count incrementation.
}
}
// f☺ll☺w ☺n instagram ♥ ---> #cyber_saviour

//------ SINGLY LINKED LIST PROGRAM ( CREATION AND TRAVERSING ) -------X
#include<stdio.h>
#include<conio.h>
struct node
{
int info;
struct node *link;
};
struct node *first;
int main()
{
void create();
void traverse();
create();
traverse();
return 0;
}
void create()
{
struct node *cpt,*ptr;
char ch;
ptr=(struct node*)malloc(sizeof(struct node));
printf("enter the data \n");
scanf("%d",&ptr->info);
first=ptr;
do
{
cpt=(struct node*)malloc(sizeof(struct node));
printf("enter the data \n");
scanf("%d",&cpt->info);
ptr->link=cpt;
ptr=cpt;
printf("Do you want to create a new node <Y/N> :\n");
ch=getch();
}
while(ch=='y');
ptr->link=NULL;
}
void traverse()
{
struct node *ptr;
ptr=first;
while(ptr!=NULL)
{
printf("The entered nodes are:%d \n",ptr->info);
ptr=ptr->link;
}
}

#include <stdio.h>
void addNodeAtHead(void **head, void *node){
void *prH=*head;
*head=node;
node->next=prH;
}

Related

Adding a node at the beginning of a Singly Linked List (C)

The code works without error but I cant seem to know why the new node is not being inserted to the beginning of the list. It probably has something to do with the else statement in the first function (insertNode) but I'm not sure, what's going on?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *link;
};
void insertNode(struct node *head, int x) {
//Create node to be added and add the input integer to it
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = x;
//Check if there are any existing nodes in the list, if not, the let the head be equal to the new temp pointer
if (head == NULL) {
head = temp;
} else {
//If not, then we need to add the node to the beginning
temp->link = head;
head = temp;
printf("Node was added successfully!\n");
}
}
int findsize(struct node *head) {
//Finds the size of the list
struct node *temp = head;
int count = 0;
while (temp != NULL) {
count++;
temp = temp->link;
}
return count;
}
void printData(struct node *head) {
//Prints the elements of the list
struct node *temp = head;
while (temp != NULL) {
printf("Element: %d\n", temp->data);
temp = temp->link;
}
}
void main() {
//Created a node and allocated memory
struct node *head;
head = (struct node *)malloc(sizeof(struct node));
//Added data to the node and created another one linked to it
head->data = 15;
head->link = (struct node *)malloc(sizeof(struct node));
head->link->data = 30;
head->link->link = NULL;
//Used the above function to add a new node at the beginning of the list
insertNode(head, 5);
//Print the size of the list
printf("The size of the list you gave is: %d\n", findsize(head));
//Print the elements of the list
printData(head);
}
When you insert a node at the beginning of the list, you effectively change the beginning of the list, so this new initial node must be returned to the caller. The prototype for insertNode() must be changed to return the list head or to take a pointer to the list head.
Here is a modified version with the first approach:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *link;
};
struct node *insertNode(struct node *head, int x) {
//Create node to be added and add the input integer to it
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if (temp != NULL) {
temp->data = x;
temp->link = head;
}
return temp;
}
int findsize(struct node *head) {
//Find the size of the list
struct node *temp = head;
int count = 0;
while (temp != NULL) {
count++;
temp = temp->link;
}
return count;
}
void printData(struct node *head) {
//Prints the elements of the list
struct node *temp = head;
while (temp != NULL) {
printf("Element: %d\n", temp->data);
temp = temp->link;
}
}
void main() {
//Created a node and allocated memory
struct node *head = NULL;
//Insert 3 nodes with values 30, 15 and 5
head = insertNode(head, 30);
head = insertNode(head, 15);
head = insertNode(head, 5);
//Print the size of the list
printf("The size of the list you gave is: %d\n", findsize(head));
//Print the elements of the list
printData(head);
//Should free the nodes
return 0;
}

LinkedList length, access and implementation via a heap. C

I am trying to print the length of a linked list I created in another .c file called linklist.c from the main.c file. It is not working and I believe is has something to do with pointers and/or memory management over all. I call into question the heap mainly here. some guidance would be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include "node.h"
int main()
{
printf("Hello world!\n");
struct node* mylist = BuildOneTwoThree();
int length = Length(mylist);
printf(mylist->data);
printf(length);
return 0;
}
#include "node.h"
#include <stdio.h>
#include <stdlib.h>
// Return the number of nodes in a list (while-loop version)
int Length(struct node** head) {
int count = 0;
struct node* current = head;
while (current != NULL) {
count++;
current = current->next;
}
return(count);
}
/*
Build the list {1, 2, 3} in the heap and store
its head pointer in a local stack variable.
Returns the head pointer to the caller.
*/
struct node* BuildOneTwoThree() {
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = malloc(sizeof(struct node)); // allocate 3 nodes in the heap
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
head->data = 1; // setup first node
head->next = second; // note: pointer assignment rule
second->data = 2; // setup second node
second->next = third;
third->data = 3; // setup third link
third->next = NULL;
// At this point, the linked list referenced by "head"
// matches the list in the drawing.
return head;
}
/*
Takes a list and a data value.
Creates a new link with the given data and pushes
it onto the front of the list.
The list is not passed in by its head pointer.
Instead the list is passed in as a "reference" pointer
to the head pointer -- this allows us
to modify the caller's memory.
*/
void Push(struct node** headRef, int data) {
struct node* newNode = malloc(sizeof(struct node));
newNode->data = data;
newNode->next = *headRef; // The '*' to dereferences back to the real head
*headRef = newNode; // ditto head points to new node
}
// Given a list and an index, return the data
// in the nth node of the list. The nodes are numbered from 0.
// Assert fails if the index is invalid (outside 0..lengh-1).
int GetNth(struct node* head, int index) {
struct node* current = head;
int answer = 0;
int x = index;
if(x <= 0 || x >= sizeof(head)-1 )
{
return -1;
}
for(int i = 0; i <= sizeof(head)-1; i++){
if (i == x){
return current->data;
}
current = current->next;
}
}
As you can see I use the BuildOneTwoThree function to build the linkedlist and am writing appropriate functions...It crashes when I try to access mylist into output.
For the most part the code seems to function from the point of view of the question only, printf had to be properly formatted.
printf("%i", length);
type cast malloc required
Change **head to *head in function argument Length
Use proper printf statement.
This question is limited to printing lenght of link list. please find code below:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* BuildOneTwoThree();
int Length(struct node* head);
int main()
{
printf("Hello world!\n");
struct node* mylist = BuildOneTwoThree();
int length = Length(mylist);
printf("data =%d\n",mylist->data);
printf("length = %d",length);
return 0;
}
// Return the number of nodes in a list (while-loop version)
int Length(struct node* head) {
int count = 0;
struct node* current = head;
while (current != NULL) {
count++;
current = current->next;
}
return(count);
}
/*
Build the list {1, 2, 3} in the heap and store
its head pointer in a local stack variable.
Returns the head pointer to the caller.
*/
struct node* BuildOneTwoThree() {
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = (struct node *)malloc(sizeof(struct node)); // allocate 3 nodes in the heap
second = (struct node *)malloc(sizeof(struct node));
third = (struct node *)malloc(sizeof(struct node));
head->data = 1; // setup first node
head->next = second; // note: pointer assignment rule
second->data = 2; // setup second node
second->next = third;
third->data = 3; // setup third link
third->next = NULL;
// At this point, the linked list referenced by "head"
// matches the list in the drawing.
return head;
}

Segmentation Fault when creating a queued list of objects

Task is to create objects in the main and have them passed to other functions, which will create a list of type queue. That's the algorithm I'm using:
Write a function of type Node * which will return a pointer to the last Node of the list
To insert a Node at the end of the list, it's required to get a pointer to the last Node
Create a new Node
Assign the newly created Node the object that's been passed to the function
Make next from the last Node point the new one
Here's the code:
typedef struct Node{
int val;
char str[30];
struct Node *next;
}Node;
void printList(const Node * head);
void queue(Node *head, Node *object);
Node *getLast(Node *head);
int main(void){
Node *head = NULL;
Node *object = (Node *)malloc(sizeof(Node));
int c = 0;
while(1){
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->val);
if(!object->val){
puts("You've decided to stop adding Nodes.");
break;
}
fflush(stdin);
printf("This string will be stored in Node %d.\n", c);
fgets(object->str, 30, stdin);
if(!(strcmp(object->str, "\n\0"))){
puts("You've decided to stop adding Nodes.");
break;
}
queue(head, object);
}
printList(head);
return 0;
}
void printList(const Node *head){
if(head == NULL){
puts("No list exists.");
exit(1);
}
while(1){
printf("|||Int: %d|||String: %s|||\n", head->val, head->str);
if(head->next){
head = head->next;
}
else{
break;
}
}
}
Node *getLast(Node *head){
if(head == NULL){
return NULL;
}
while(head->next){
head = head ->next;
}
return head;
}
void queue(Node *head, Node *object){
Node *last = getLast(head);
Node *tmp = (Node *)malloc(sizeof(Node));
*tmp = *object;
tmp -> next = NULL;
last -> next = tmp;
}
Maybe the problem is in having getLast return NULL. But then again, this exact same thing worked when I created a list consisting only of int.
As pointed out in the comment section, last->next = tmp fails for first call to queue() as getLast() returns NULL. A correct solution would be like this:
void queue(Node **head, Node *object){
Node *last = getLast(*head);
Node *tmp = (Node *)malloc(sizeof(Node));
*tmp = *object;
tmp -> next = NULL;
if (last != NULL)
last -> next = tmp;
else
*head = tmp;
}
and call queue(&head, object) from main().

Display circular list endless loop

I have two functions:
void display(struct node *start) {
struct node *ptr;
ptr = start;
while (ptr -> next != start) {
printf("\t %d", ptr -> data);
ptr = ptr -> next;
}
printf("\t %d", ptr -> data);
}
struct node *insert_beg(struct node *start) {
struct node *new_node;
new_node = (struct node *)malloc(sizeof(struct node));
printf("\n Enter data : ");
scanf("%d", &new_node -> data);
new_node -> next = start;
start = new_node;
return start;
}
After using insert_beg(start) and trying to display this list using display(start), I have an endless loop.
Thanks for your support.
You are not creating a circular list here.
For creating circular list you have to handle one more case when there is no element in the list i.e. start is NULL (list is empty).
Make following edit to it after the scanf part of insert_beg() function :
if(start == NULL){ // this is the required condition to be added
start = new_node;
start->next = start;
}
else{
// this code for adding element is to be performed only when list is not empty
struct node *tmp = start->next;
start->next = new_node;
new_node->next = temp;
}
I hope it will solve your problem !!
Because you didn't provided a complete example how do you build the circular list, let me assume that you are using the insert_beg function wrong.
If I use your function like follows, there is no endless loop:
int main() {
struct node* start;
start = (struct node*)malloc(sizeof(struct node));
start->data = 1;
start->next = start; /* initializing the next pointer to itself */
start->next = insert_beg(start->next);
start->next = insert_beg(start->next);
start->next = insert_beg(start->next);
display(start);
return 0;
}
I see an issue in your insert_beg too:
start = new_node;
If you intend to overwrite where the start points to, then you have to change your function signature to the following:
struct node *insert_beg(struct node **start);
Then inside the function you can do the following:
new_node->next = *start; /* access the pointer pointed by start */
*start = new_node; /* overwrite where the pointer pointed by start points to*/
return *start; /* losts its meaning */
The modifications above let you use your insert_beg function as follows:
insert_beg(&start->next);
insert_beg(&start->next);
insert_beg(&start->next);

C: How to free nodes in the linked list?

How will I free the nodes allocated in another function?
struct node {
int data;
struct node* next;
};
struct node* buildList()
{
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = malloc(sizeof(struct node));
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
return head;
}
I call the buildList function in the main()
int main()
{
struct node* h = buildList();
printf("The second element is %d\n", h->next->data);
return 0;
}
I want to free head, second and third variables.
Thanks.
Update:
int main()
{
struct node* h = buildList();
printf("The element is %d\n", h->next->data); //prints 2
//free(h->next->next);
//free(h->next);
free(h);
// struct node* h1 = buildList();
printf("The element is %d\n", h->next->data); //print 2 ?? why?
return 0;
}
Both prints 2. Shouldn't calling free(h) remove h. If so why is that h->next->data available, if h is free. Ofcourse the 'second' node is not freed. But since head is removed, it should be able to reference the next element. What's the mistake here?
An iterative function to free your list:
void freeList(struct node* head)
{
struct node* tmp;
while (head != NULL)
{
tmp = head;
head = head->next;
free(tmp);
}
}
What the function is doing is the follow:
check if head is NULL, if yes the list is empty and we just return
Save the head in a tmp variable, and make head point to the next node on your list (this is done in head = head->next
Now we can safely free(tmp) variable, and head just points to the rest of the list, go back to step 1
Simply by iterating over the list:
struct node *n = head;
while(n){
struct node *n1 = n;
n = n->next;
free(n1);
}
One function can do the job,
void free_list(node *pHead)
{
node *pNode = pHead, *pNext;
while (NULL != pNode)
{
pNext = pNode->next;
free(pNode);
pNode = pNext;
}
}
struct node{
int position;
char name[30];
struct node * next;
};
void free_list(node * list){
node* next_node;
printf("\n\n Freeing List: \n");
while(list != NULL)
{
next_node = list->next;
printf("clear mem for: %s",list->name);
free(list);
list = next_node;
printf("->");
}
}
You could always do it recursively like so:
void freeList(struct node* currentNode)
{
if(currentNode->next) freeList(currentNode->next);
free(currentNode);
}

Resources