sorting element from linked list - c

void sortlist()
{
struct node *a;
struct node *temp=head;
struct node *temp1=head->next;
while(temp!=NULL)
{
while(temp1->next!=NULL)
{
if(temp->data > temp1->data)
{
a->data=temp->data;
temp->data=temp1->data;
temp1->data=a->data;
}
else
{
temp1=temp1->next;
}
}
temp=temp->next;
}
}
//I am new to data structures.i am encountering some problem here while trying to sort elements of linked list.list does not get sorted.any help is greatly appreciated.

a is an uninitialised pointer so the line
a->data=temp->data;
invokes undefined behaviour. Crashing is the most likely result here as you'll try to write to memory at an undefined address that may not be writeable by your code or may be in use by another part of your program.
You could fix this by giving a the same type as temp->data instead.
void sortlist()
{
int a; // change type to match node->data if required
...
if(temp->data > temp1->data)
{
a=temp->data;
temp->data=temp1->data;
temp1->data=a
}
...
}
EDIT: There is also a potential NULL dereference crash in the line while(temp1->next!=NULL). The code below shows a potential implementation of sortlist which avoids this.
void sortlist()
{
struct node *ptr=head;
while(ptr!=NULL) {
struct node *next;
if (ptr == NULL)
return;
next = ptr->next;
while(next!=NULL) {
if(ptr->data > next->data) {
int a=ptr->data;
ptr->data=next->data;
next->data=a;
}
next = next->next;
}
ptr=ptr->next;
}
}

I made changes in the code and add the comments for the changes
void sortlist()
{
// struct node *a; /* this is not required. */
/* NULL checks are required,if head is NULL,head->next will crash.*/
if(head == NULL || head->next == NULL) return;
struct node *temp=head;
struct node *temp1=head->next;
while(temp!=NULL)
{
while(temp1->next!=NULL)
{
if(temp->data > temp1->data)
{
/* assuming you data is integer*/
int d=temp->data;
temp->data=temp1->data;
temp1->data=d;
}
//else /* else is not required, better to remove it.*/
//{
temp1=temp1->next;
//}
}
temp=temp->next;
}
}

//at last i found answer to my own problem and this is the solution,thanks for your help buddies
void sortlist()
{
struct node *temp=head;
int s;
struct node *temp1=temp->next;
while(temp!=NULL)
{
temp1=temp->next;
while(temp1!=NULL)
{
if(temp->data > temp1->data)
{
s=temp->data;
temp->data=temp1->data;
temp1->data=s;
}
temp1=temp1->next;
}
temp=temp->next;
}
}

Related

MultiThreading with LinkedList

I need to make three threads with shared access to linkedlist: searching,adding,removing thread. Seaching thread only browsing through list. Adding threads add item at the end of list and they are mutual exclusive (protected by mutex) but you can searching and adding at the same time. Removing threads remove item from any point at the list and they are mutal exclusive with adding and searching.
My linked list:
struct node
{
int data;
struct node *next;
}
void search(int num)
{
int flag = 0;
struct node *temp;
temp = start;
while(temp!=NULL)
{
if(temp->data == num)
return(temp); //Found
temp = temp->next;
}
if(flag == 0)
return(start); // Not found
}
void insert(int num)
{
int c=0;
struct node *temp;
temp=head;
if(temp==NULL)
{
add(num);
}
else
{
while(temp!=NULL)
{
if(temp->data<num)
c++;
temp=temp->next;
}
if(c==0)
add(num);
else if(c<count())
addafter(num,++c);
else
append(num);
}
}
int delete(int num)
{
struct node *temp, *prev;
temp=head;
while(temp!=NULL)
{
if(temp->data==num)
{
if(temp==head)
{
head=temp->next;
free(temp);
return 1;
}
else
{
prev->next=temp->next;
free(temp);
return 1;
}
}
else
{
prev=temp;
temp= temp->next;
}
}
return 0;
}
If anyone could show me way how to do with threads and mutex I will be so thankful
Assuming you are using pthread.h.
First you should add a struct for you linked list:
typedef struct
{
struct node *first;
pthread_mutex_t list_mutex;
} *List;
And then add pthread_mutex_lock(&list_mutex); to the start of each function and pthread_mutex_unlock(&list_mutex); to the end.
Also your functions should receive a List as an argument, so you need to change the function definitions.
You should read about Pthread mutex locks.

The link list is not printing the value after first iteration [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 6 years ago.
Improve this question
I just made a program of double linked list in which I was trying to print the values after every insertion operation done.
After first insertion no value is being printed but from the second insertion the value is printing fine(except the first one).
I am hereby attaching the full code
// Double Linked List
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next,*prev;
};
struct node *head;
struct node *getnewnode(int);
void insertathead(int);
void insertattail(int);
void display();
void rev_display();
void main()
{
char c;
int n,n1;
clrscr();
head = NULL;
do
{
printf("\n Enter Data Element");
scanf("%d", &n);
printf("Press 1 to insert at beginning \n Press 2 to insert at the end");
scanf("%d", &n1);
if(n1 == 1)
{
insertathead(n);
display();
rev_display();
}
if(n1 == 2)
{
insertattail(n);
display();
rev_display();
}
printf("Do you wish to enter more (Y/N)");
c = getch();
} while(c == 'Y' || c == 'y');
getch();
}
struct node *getnewnode(int x)
{
struct node *newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return(newnode);
}
void insertathead(int x)
{
struct node *temp = getnewnode(x);
if(head == NULL)
{
head = temp;
}
else
{
head->prev = temp;
temp->next = head;
head = temp;
}
}
void display()
{
struct node *temp;
temp = head;
printf("Forward:\n");
while(temp->next != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
void rev_display()
{
struct node *temp;
temp = head;
while(temp->next != NULL)
{
temp = temp->next;
}
while(temp->prev != NULL)
{
printf("%d ", temp->data);
temp = temp->prev;
}
}
void insertattail(int x)
{
struct node *temp = getnewnode(x);
struct node *t;
t = head;
while(t->next != NULL)
{
t = t->next;
}
t->next = temp;
temp->prev = t;
}
The error is in the definition of the while loop. You stop when you reach a setting with no previous entry. You should stop when the current entry is NULL
Also note that in your original you call rev_display() but you defined the function as rev_dispaly(). That typo should be fixed.
You also assume that insertattail() never has a case in which the list is empty (head == NULL) I will show how that occurs after the rev_display fix.
void rev_display()
{
struct node *temp;
temp=head;
// This correctly finds the last entry
while(temp->next!=NULL)
{
temp=temp->next;
}
/* This will stop when you reach the entry with no previous entry */
while(temp->prev!=NULL)
{
printf("%d ",temp->data);
temp=temp->prev;
}
}
The code should really be
void rev_display()
{
struct node *temp;
temp=head;
// This correctly finds the last entry
while(temp->next!=NULL)
{
temp=temp->next;
}
/* This will correctly include the head as well in the print */
while(temp != NULL)
{
printf("%d ",temp->data);
temp=temp->prev;
}
}
You do not check for the empty list case in insertattail().
void insertattail(int x)
{
struct node *temp=getnewnode(x);
struct node *t;
t=head;
// Note that this assumes that the list is not empty
while(t->next!=NULL)
{
t=t->next;
}
t->next=temp;
temp->prev=t;
}
This needs to check for the empty list.
void insertattail(int x)
{
struct node *temp=getnewnode(x);
struct node *t;
// First check if the list is empty
if(head==NULL)
{
head=temp;
head->next = NULL;
head->prev = NULL;
}
else
{
t=head;
// This list is not empty so find the end
while(t->next!=NULL)
{
t=t->next;
}
t->next=temp;
temp->prev=t;
}
}

LinkedList Delete End in C

I am trying to program a simple text editor in C and I am using LinkedList. I have problems with the deleteEnd function. Where did I go wrong?
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
i store the character, and the coordinates of the character in a structure like this:
struct node {
struct node *previous;
char c;
int x;
int y;
struct node *next;
}*head;
This is called whenever a letter is typed in.
void characters(char typed, int xpos, int ypos) //assign values of a node
{
struct node *temp,*var,*temp2;
temp=(struct node *)malloc(sizeof(struct node));
temp->c=typed;
temp->x=xpos;
temp->y=ypos;
if(head==NULL)
{
head=temp;
head->next=NULL;
}
else
{
temp2=head;
while(temp2!=NULL)
{
var=temp2;
temp2=temp2->next;
}
temp2=temp;
var->next=temp2;
temp2->next=NULL;
}
}
Print the new node if there are changes.
void printer() //to print everything
{
struct node *temp;
temp=head;
while(temp!=NULL)
{
gotoxy(temp->x,temp->y);
printf("%c",temp->c);
temp=temp->next;
}
}
Now here, I do not know why the last element of the head won't be deleted.
void deletesEnd()
{
struct node *temp,*last;
temp=head;
while(temp!=NULL)
{
last=temp;
temp=temp->next;
}
if(last->previous== NULL)
{
free(temp);
head=NULL;
}
last=NULL;
temp->previous=last;
free(temp);
}
This is where it all begins.
main()
{
char c; //for storing the character
int x,y; //for the position of the character
clrscr();
for(;;)
{
c=getch();
x=wherex();
y=wherey();
if(c==0x1b) //escape for exit
{
exit(0);
}
else if (c==8) //for backspace
{
deletesEnd();
// clrscr();
printer();
}
else //normal characters
{
characters(c,x,y);
printer();
}
}
}
Try this :
void deletesEnd()
{
struct node *temp,*last;
temp=head;
last = temp;
while(temp != NULL && temp->next!=NULL)
{
last=temp;
temp=temp->next;
}
if(last == temp)
{
free(temp);
head=NULL;
} else {
free(last->next);
last->next = NULL;
}
In your algorithm, you try to work with a NULL pointer, so you can't get to the previous node I think.
For finding the last node in the list, the simplest is to loop until the next pointer is NULL.
For deletion at the end you also need to keep track of the next-to-last node, and it could look something like this:
struct node *prev, *curr;
for (prev = NULL, curr = head; curr->next != NULL; prev = curr, curr = curr->next)
;
/* `curr` is now the last node in the list, `prev` is the next-to-last node */
if (prev != NULL)
prev->next = NULL; /* Unlink the last node */
else
head = NULL; /* List was only one node long */
/* Free the memory for the last node */
free(curr);
If you properly kept the list double-linked the loop would be even easier, as you don't have to keep track of the next-to-last node anymore:
struct node *node;
for (node = head; node->next != NULL; node = node->next)
;
/* `node` is now the last node in the list */
if (node->previous != NULL)
node->previous->next = NULL; /* Unlink last node */
else
head = NULL; /* List was only one node long */
/* Free the memory for the last node */
free(curr);
And keeping track of the tail from the start will make this much simpler:
if (tail != NULL)
{
struct node *node = tail;
if (node->previous != NULL)
{
node->previous->next = NULL; /* Unlink last node */
tail = node->previous;
}
else
head = tail = NULL; /* Removing last node in list */
free(node);
}
try this
void deletesEnd()
{
struct node *temp,*last;
temp=head;
while(temp!=NULL)
{
last=temp;
temp=temp->next;
}
if(last->previous== NULL)
{
free(temp);
head=NULL;
}
last->previous->next = NULL;
last=NULL;
temp->previous=last;
free(temp);
}
you see, you've put the last element in the list in last, and then did last=NULL; which just put null in last variable. temp is already NULL so temp->previous=last; has no meaning.
you need that the last item's previous item will point to NULL as the line
last->previous->next = NULL;
does
Linkedlist work with only two simple generic rules...
First Make the link
Second after make, Break the link.
Just check the condition...
If you have empty list
if list has only one node
if it has more then one node
try these rules. I hope it will work for you.
This line :
temp->previous=last;
will cause you problems since temp is null at that point already (since it was the termination condition in the while loop).
Change your method to :
void deletesEnd()
{
struct node *temp,*last;
temp=head;
while(temp!=NULL)
{
last=temp;
temp=temp->next;
}
if(last != NULL) {
if (last->previous != null) { // Last element gonig to be deleted so the previous element if exists should point his next to null (end of list)
last->previous->next = null;
}
free(last); // Free the last element in the list
}
}

Segmentation Fault and Strange Output in Deletion function in Doubly Linked List

Here my code is showing segmentation fault in the function delete_node which deletes the node with given number from the doubly linked list. It is showing segmentation fault if I delete the first element or the last element. If I try to delete the elements in between it simply replaces its value with "0". Also please tell why the commented command in the function printlist shows segmentation fault when I uncomment it.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *prev;
struct node *next;
};
struct node *first=NULL;
struct node *insertatbeg(struct node* list,int number)
{
struct node *new_node=malloc(sizeof(struct node));
new_node->data=number;
new_node->next=list;
new_node->prev=NULL;
return new_node;
}
struct node *insertatend(struct node* list,int number)
{
struct node* new_node;
struct node *curr=list;
new_node=malloc(sizeof(struct node));
new_node->data=number;
if(list==NULL)
{
new_node->next=list;
new_node->prev=NULL;
return new_node ;
}
else
{
while(curr->next!=NULL)
{
curr=curr->next;
}
curr->next=new_node;
new_node->next=NULL;
new_node->prev=curr;
return list;
}
}
///Till here no error for sure
////////////////////////////////////////////////////////
void printlist(struct node *list)
{
int i=0;
struct node *p;
for(p=list;p!=NULL;p=p->next)
{
//printf("\nCurr=%d Prev=%d Next=%d\n",p->data,(p->prev)->data,(p->next)->data);//uncomment this & Error(Segmentation Fault comes)
printf("%d->",p->data);
++i;
}
printf("NULL\n");
printf("size=%d\n",i);
}
////////////////////////////////////////////
struct node *delete_node(struct node *list, int number)
{
struct node *curr,*previous;
for(curr=list,previous=NULL;curr!=NULL && curr->data!=number; previous=curr,curr=curr->next, (curr->next)->prev=previous)
;
if(curr==NULL)
{
printf("Sorry..Could not find the element..!!!\n");
return list;
}
if(curr->prev==NULL)
{
(curr->next)->prev=NULL;
free(curr);
return list;
}
if(curr->next==NULL)
{
(curr->prev)->next=NULL;
free(curr);
return list;
}
else
{
(curr->prev)->next=curr->next;
(curr->next)->prev=curr->prev;
free(curr);
return list;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
}
int main()
{
first=insertatbeg(first,3);
first=insertatend(first,2);
first=insertatbeg(first,1);
//Till here output is fine and is 1->3->2
printlist(first);
//first=delete_node(first,1);
//first=delete_node(first,2);
first=delete_node(first,3);
printlist(first);
return 0;
}
The pointer values might be NULL. You should add checks in the code for that case.
if(pointer != NULL)
{
// execute the code
}
Also please tell why the commented command in the function printlist shows segmentation fault when I uncomment it.
For the first and last element of the list prev and next elements will be null,
that throws segfaults, because you try to access invalid memory.
Since you've a double linked list you don't need to maintain to two pointers,
you can delete more simply like this:
struct node *delete_node(struct node *list, int number)
{
struct node *c;
for (c = list; c != NULL && c->data != number; c = c->next)
;
if (c == NULL) return list; //if node not found
if (c->next == NULL && c->prev == NULL) //if the only element in
return NULL; //list has to be deleted
if (c->prev != NULL)
c->prev->next = c->next;
else list = c->next; //if first element is to be deleted
if (c->next != NULL)
c->next->prev = c->prev;
return list;
}

How to free node after deletion in linklist in C

I have a very basic doubt. I created a linklist using structure and this is my delete code.
void delete(int num)
{
struct node* temp=head;
struct node* prev=head;
if(temp == NULL)
printf("List Empty\n");
else
{
while(temp != NULL)
{
if(temp->value == num)
{
prev=temp->next;
free(temp);
break;
}
else
{
prev=temp;
temp=temp->next;
}
}
After running this code, the node is not getting deleted. If I print temp->value after free(temp), the value is 0. But this should not be the case. The free should wipe the node. So I don't understand from where the 0 appears. Any idea what is wrong with this code ?
My show function:
void show()
{
struct node *temp = head;
while(temp != NULL)
{
printf("---- %d ---- ", temp->value);
temp=temp->next;
}
printf("\n\n");
}
My struct:
struct node
{
int value;
int pos;
struct node* next;
};
Thanks.
When you find the node in delete:
if(temp->value == num)
{
prev=temp->next;
free(temp);
break;
}
You don't actually make the previous nodes next-pointer point to the nodes next link.
Instead you should do e.g.
prev->next = temp->next;

Resources