Create an ordered single linked list with numbers - c

So up until now this is the code I have. I'm having problems implementing the main function because linked-lists are a new subject for me. Could someone explain me what should I include to have an output like this
The output should look like that after inserting 2, 0, 3, 5 and 4 in an, initially, empty list:
2
0 2
0 2 3
0 2 3 5
0 2 3 4 5
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int number;
struct node *next;
} NODE;
NODE* insert(NODE *, int);
NODE* delete(NODE *, int);
void traverse(NODE *);
NODE * search(NODE *head, int data);
main(){
list *newnode, *start = NULL; // this will point to the first node of the list
}
NODE *search(NODE *head, int data){ //search for the right position to add data
NODE *previous=NULL;
NODE *current=head;
while (current !=NULL && data > current->number)
{
previous=current;
current= current->next;
}
return previous;
}
NODE *insert(NODE *head, int data){ //allocates a new node with data value
NODE * temp;
if (temp = (NODE *)malloc(sizeof(NODE)==(NODE*)NULL))
return 1; //malloc have failed
temp->number = data;
NODE *previous;
previous=search(head,data);
//two cases 1) add at front 2)add elsewhere
if (previous==NULL)
{
temp->next=head;
head=temp;
}
else
{
temp->next = previous->next;
previous->next = temp;
}
return head;
}
void traverse (NODE *head){
NODE * current = head;
while (current != NULL)
{
printf(" %d ", current->number);
current = current->next;
}
printf("\n");
}
NODE* delete(NODE *head, int data)
{
NODE *previous, *temp;
previous=search(head,data);
if(previous==NULL && head->number==data)
{
temp=head;
head=head->next;
free(temp);
}
else if (previous->next !=NULL && previous->next->number==data)
{
temp=previous->next;
previous->next = previous->next->next;
free(temp);
}
return head;
}

void printList (list *currentPtr)
{
if (currentPtr == NULL)
printf("list is empty.\n\n");
else
{
printf("The list is:\n");
while (currentPtr != NULL){
printf("%d --> ", currentPtr->number);
currentPtr = currentPtr ->next;
}
printf("NULL\n\n");
}
}
The list is:
0 -> 2 -> 3 -> 4 -> 5 -> NULL
Yo can take away the NULL and the -> if you want.

Related

getting segmentation error (core dumped) in linked list

I have looked at my code several times but couldn't find the problem. please tell me what I need to replace to get my code working.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
void insert(int x)
{
struct node *temp=(struct node *)malloc(sizeof(struct node));
temp->data = x;
temp->next = NULL;
if (head == NULL)
{
temp->next = head;
head = temp;
return;
}
struct node *temp1 = head;
while(temp1 != NULL)
{
temp1 = temp1->next;
}
temp1->next = temp;
}
void display()
{
struct node *temp = head;
if (head == NULL)
{
printf("list is empty");
return;
}
else{
while(temp!=NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
}
}
int main()
{
head = NULL;
insert(3);
insert(5);
insert(6);
display();
}
The problem is in this code:
struct node *temp1=head;
while(temp1!=NULL)
{
temp1=temp1->next;
}
temp1->next=temp;
... the while loop won't end until temp1 is NULL, so after the loop ends, it is guaranteed that temp1 is a NULL pointer ... and then you dereference that NULL pointer (via temp1->next), which causes a crash. Probably what you want to do instead is while(temp1->next != NULL) {...}
while(temp1!=NULL)
{
temp1=temp1->next;
}
temp1->next=temp;
The only way out of this loop is for temp1 to be NULL. Then the next line attempts to used temp1 as a pointer. This is likely causing your issue. You need to instead check if the next is NULL and break leaving temp1 as the last in the list not it's next.
Pro tip for linked lists like this, they are a lot easier to modify with double pointers. Example code:
void append(struct node **list, int a) {
// skip to the end of the list:
while (*list != NULL) {
list = &(*list)->next;
}
*list = malloc(sizeof(struct node));
(*list)->data = a;
(*list)->next = NULL;
}
void display(struct node *list) {
while (list) {
printf("%d\n", list->data);
list = list->next;
}
}
void remove(struct node **list, int index) {
while (*list) {
if (--index == 0) {
struct node *temp = *list;
*list = temp->next;
free(temp);
break;
}
}
}
int main() {
struct list *mylist;
append(&mylist, 3);
append(&mylist, 4);
append(&mylist, 5);
display(mylist); // prints 3 4 5
remove(&mylist, 1);
display(mylist); // prints 3 5
remove(&mylist, 0);
remove(&mylist, 0);
// mylist is NULL again, all memory free'd
}
Note that this code needs no special cases for "is the list empty?", which makes it less complex than yours.

Linked List using recursion - Unexpected Output

I found this on Internet to reverse a list using recursion and applied it in codeblocks but the output only reverse prints last two Insert call from main function. It skips the first three Insert calls. Why? I did search for this problem here but I failed to understand them as I'm a beginner. Kindly help
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node * head;
struct Node* Insert (struct Node* head, int data)
{
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
if(head == NULL)
{
head = temp;
return;
}
struct Node* temp2 = head;
while(temp2->next != NULL)
{
temp2 = temp2->next;
}
temp2->next = temp;
}
void reversePrint(struct Node* head)
{
if(head == NULL)
{
printf("\n");
return;
}
reversePrint(head->next);
printf(" %d ", head->data);
return;
}
int main()
{
struct Node* head = NULL;
head = Insert(head,2);
head = Insert(head,7);
head = Insert(head,3);
head = Insert(head,1);
head = Insert(head,4);
reversePrint(head);
return 0;
}
O/P : 4 1
NOTES:
Don't cast the return of value of malloc
You declared two *head and confused yourself
No need to pass pointer to function and return pointer when you have head declared as global. Which is not a good idea but I followed your code.
Code:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node * head;
void Insert (int data)
{
struct Node* temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
if(head == NULL)
{
head = temp;
return;
}
struct Node* temp2 = head;
while(temp2->next != NULL)
{
temp2 = temp2->next;
}
temp2->next = temp;
}
void reversePrint(struct Node* head)
{
if(head == NULL)
{
printf("\n");
return;
}
reversePrint(head->next);
printf(" %d ", head->data);
return;
}
int main()
{
Insert(2);
Insert(7);
Insert(3);
Insert(1);
Insert(4);
reversePrint(head);
return 0;
}
OUTPUT:
4 1 3 7 2

Sort a Linked list using C

I am trying to sort a Linked list, but not able to do it. Below is my code. Can anyone help me. I have seen some programs too, which sort linked list and their approach is also like this only.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int push(struct node **h, int x)
{
struct node *temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
temp->next = *h;
*h = temp;
return 0;
}
void print(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}
void sort(struct node **h)
{
int i,j,a;
struct node *temp1;
struct node *temp2;
for(temp1=*h;temp1!=NULL;temp1=temp1->next)
{
for(temp2=temp1->next;temp2!=NULL;temp2=temp2->next)
{
a = temp1->data;
temp1->data = temp2->data;
temp2->data = a;
}
}
}
int main()
{
struct node * head = NULL;
push(&head,5);
push(&head,4);
push(&head,6);
push(&head,2);
push(&head,9);
printf("List is : ");
print(head);
sort(&head);
printf("after sorting list is : ");
print(head);
return 0;
}
Below is the output which i am getting :
List is : 9 2 6 4 5
after sorting list is : 5 4 6 2 9
You're switching the elements no matter what. Compare them first and then swap them if temp2 is less than temp1:
void sort(struct node **h)
{
int i,j,a;
struct node *temp1;
struct node *temp2;
for(temp1=*h;temp1!=NULL;temp1=temp1->next)
{
for(temp2=temp1->next;temp2!=NULL;temp2=temp2->next)
{
if(temp2->data < temp1->data)
{
a = temp1->data;
temp1->data = temp2->data;
temp2->data = a;
}
}
}
}
In your bubble sort, you forget the swap condition.
In my opinion, I suggest insertion sort
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int push(struct node **h, int x)
{
struct node *temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
if (*h == NULL) {
temp->next = *h;
*h = temp;
} else {
struct node *tmp = *h;
struct node *prev = NULL;
while (1) {
if (tmp == NULL || tmp->data >= temp->data)
break;
prev = tmp;
tmp = tmp->next;
}
temp->next = tmp;
if (prev != NULL)
prev->next = temp;
else
*h = temp;
}
return 0;
}
void print(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}
int main()
{
struct node * head = NULL;
push(&head,5);
push(&head,4);
push(&head,6);
push(&head,2);
push(&head,9);
printf("List is : ");
print(head);
//sort(&head);
printf("after sorting list is : ");
print(head);
return 0;
}

Deleting a node at a given position in Linked List

Given a singly linked list and a position, i am trying to delete a linked list node at a specific position.
CODE:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node* next;
};
void printList(struct node* head_ref)
{
//struct node* head_ref = (struct node*)malloc(sizeof(struct node));
if(head_ref == NULL)
printf("The list is empty");
while(head_ref!=NULL)
{
printf("%d\n",head_ref->data);
head_ref = head_ref->next;
}
}
void insert_beg(struct node **head_ref,int new_data)
{
struct node* new_node = (struct node*)malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = *head_ref;
*head_ref = new_node;
}
void delete(struct node **head_ref,int position)
{
int i=1;
if(*head_ref == NULL)
return;
struct node *tails,*temp = *head_ref;
if(position == 0)
{
*head_ref = temp->next;
free(temp);
return;
}
while(temp->next!=NULL)
{
tails = temp->next;
temp = temp->next;
if(i == position)
{
tails->next = temp->next;
free(temp);
return;
}
i++;
}
}
int main()
{
struct node *head = NULL;
insert_beg(&head,36);
insert_beg(&head,35);
insert_beg(&head,34);
insert_beg(&head,33);
printList(head);
int position;
printf("Enter the position of the node u wanna delete\n");
scanf("%d",&position);
delete(&head,position);
printf("\n");
printList(head);
}
Whenever I am trying to delete a node above position 0, I am getting 0 in that specific position instead of nothing. Could I know where I am going wrong?
For eg my list is : 33 34 35 36
My Output: 33 0 35 36 (while attempting to delete node 1)
Valid Output: 33 35 36
The problem occurs due to this wrong statement
while(temp->next!=NULL)
{
tails = temp->next;
^^^^^^^^^^^^^^^^^^^
temp = temp->next;
In this case tails and temp are the same nodes. And if temp is deleted then you set the data member next of the deleted node to temp->next
if(i == position)
{
tails->next = temp->next;
^^^^^^^^^^^^^^^^^^^^^^^^^
Here tails is node that will be deleted.
You should change the data member next of the node before the deleted node. So the wrong statement should be updated like
while(temp->next!=NULL)
{
tails = temp;
^^^^^^^^^^^^^
temp = temp->next;
As for me then I would write the function the following way
int delete( struct node **head, size_t position )
{
struct node *prev = NULL;
size_t i = 0;
while ( i != position && *head != NULL )
{
prev = *head;
head = &( *head )->next;
++i;
}
int success = *head != NULL;
if ( success )
{
struct node *tmp = *head;
if ( prev == NULL )
{
*head = ( *head )->next;
}
else
{
prev->next = ( *head )->next;
}
free( tmp );
}
return success;
}
Into your delete function while loop tails and temp move forward a the same time starting fro the same address. The node is not deleted because you are always assigning the same value (in other words you are only confirm next pointer value each time).
That means that, after your cancellation, printout is UB due to the freed memory of one of the nodes.
Correcting your code:
void delete(struct node **head_ref,int position)
{
int i=1;
if(*head_ref == NULL)
return;
struct node *temp = *head_ref;
if(position == 0)
{
*head_ref = temp->next;
free(temp);
return;
}
struct node *tails = *head_ref;
while(temp->next!=NULL)
{
temp = temp->next;
if(i == position)
{
tails->next = temp->next;
free(temp);
return;
}
tails = tails->next;
i++;
}
}

Deleting front node from a Singly Linked List in C

I am trying to delete from a Singly Linked List, however, when I try to delete from the first element, it prints garbage. I think the problem comes from the delete_node function, however, I tried everything and I cannot figure it out.
#include <stdio.h>//prinf
#include <stdlib.h>//alloc mallco callo
typedef struct node node;
struct node{
int number;
node *next;
};
node *new_node(int num){
node *n= (node*) malloc(sizeof(node));
n->number=num;
n->next=NULL;
return n;
}
void node_free_all(node *n){
if(n != NULL){
node_free_all(n->next);
free(n);
}
}
void print_nodes(node *n){
if(n != NULL){
print_nodes(n->next);
printf("Number is: %d\n",n->number);
}
}
void delete_node(node *n, int num){
node *rmNode= (node*)malloc(sizeof(node));
//delete first
if( n!= NULL && n->number==num){
rmNode = n;
n=n->next;
free(rmNode);
}
//all but first
while(n != NULL){
if(n->next != NULL && n->next->number == num){
rmNode= n->next;
n->next = rmNode->next;
free(rmNode);
break;
}
n=n->next;
}
}
int main(){
int i;
node *head= (node*) malloc(sizeof(node));
node *curr;
head=NULL;
for(i=1;i<=10;i++) {
curr = new_node(i);
curr->next =head;
head=curr;
}
printf("Everything:\n");
print_nodes(head);
printf("Deleting 1:\n");
delete_node(head,1);
print_nodes(head);
printf("Deleting 5:\n");
delete_node(head,5);
print_nodes(head);
printf("Deleting 2:\n");
delete_node(head,2);
print_nodes(head);
printf("Deleting 3:\n");
delete_node(head,3);
print_nodes(head);
printf("Deleting 10:\n");
delete_node(head,10);
print_nodes(head);
printf("Deleting 9:\n");
delete_node(head,9);
print_nodes(head);
node_free_all(head);
// node_free_all(list);
return 0;
}
What am I doing wrong?
You don't need to allocate memory to rmNode. Plus you need to pass the reference of head pointer to the function delete_node because every time you are updating the list and if you have to delete first element of list, then in this case head pointer also got updated.
struct node
{
int number;
node *next;
};
void delete_node(struct node** head_ref, int num)
{
struct node* temp;
struct node* current = (*head_ref);
//delete first
if( current != NULL && current->number == num)
{
temp = current;
current = current->next;
free(temp);
(*head_ref) = current;
}
else
{
//all but first
while(current != NULL)
{
if(current->next != NULL && current->next->number == num)
{
temp = current->next;
current->next = temp->next;
free(temp);
break;
}
current = current->next;
}
}
}
here's a version that removes all items that matches num, and always update the head item.
void delete_node(node** head_ref, int num)
{
node* temp;
node* last = 0;
node* current = *head_ref;
while(current)
{
if( current->number == num )
{
temp = current;
if( current == *head_ref )
current = (*head_ref) = current->next;
else
current = last->next = current->next;
free(temp);
} else {
last = current;
current = current->next;
}
}
}
You have to call it like delete_node(&head,1);
because it needs an address to the head item to be able to change it

Resources