Finding the intersection and union of 2 singly linked list - c

The program generates the union and intersection of 2 linked lists. However, it does not generate the expected output where duplicate values from list 1 and list 2 should not be present and the intersection list is not even being displayed.
How can I resolve this issue?
`
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *next;
} node;
void insertAtBeg(node **head, int ele){
node *newnode = (node*)malloc(sizeof(node));
newnode->data = ele;
newnode->next = (*head);
(*head) = newnode;
}
int isPresent(node *temp, int ele){
node *t = temp;
while(t != NULL){
if(t->data == ele)
return 1;
t = t->next;
}
return 0;
}
void printList(node *n){
while(n != NULL){
printf("%d->",n->data);
n = n->next;
}
}
node* getUnion(node *head1,node *head2){
node *result = NULL;
node *t1 = head1;
node *t2 = head2;
while(t1 != NULL){
insertAtBeg(&result, t1->data);
t1 = t1->next;
}
while(t2!=NULL){
if(!isPresent(result, t2->data));
insertAtBeg(&result,t2->data);
t2 = t2->next;
}
return result;
}
node *getIntersection(node *head1,node *head2){
node* result = NULL;
node* t1 = head1;
while(t1 != NULL){
if(isPresent(head2, t1->data))
insertAtBeg(&result,t1->data);
t1 = t1->next;
}
return result;
}
int main(){
node *intersection = NULL;
node *unin = NULL;
node *List1;
node *List2;
List1 = List2 = NULL;
int i,n,m,temp;
printf("Enter the size of the first linked list:\n");
scanf("%d",&n);
printf("Enter %d elements\n",n);
for(i = 0;i < n;i++){
scanf("%d",&temp);
insertAtBeg(&List1,temp);
}
printf("Displaying list 1:\n");
printList(List1);
printf("\nEnter the size of the second linked list:\n");
scanf("%d",&m);
printf("Enter %d elements\n",m);
for(i = 0;i < m;i++){
scanf("%d",&temp);
insertAtBeg(&List2,temp);
}
printf("Displaying list 2:\n");
printList(List2);
unin = getUnion(List1,List2);
intersection = getIntersection(List1,List2);
printf("\nLinked List with Union of List1 and List2:\n");
printList(unin);
printf("\nLinked List with Intersection of List1 and List2:\n");
printList(intersection);
return 0;
}
`
Generated output:
Enter the size of the first linked list:
4
Enter 4 elements
3 4 6 1
Displaying list 1:
1->6->4->3->
Enter the size of the second linked list:
4
Enter 4 elements
8 9 10 1
Displaying list 2:
1->10->9->8->
Linked List with Union of List1 and List2:
8->9->10->1->3->4->6->1->
Linked List with Intersection of List1 and List2:
1->

Within the function getUnion there is a typo
while(t2!=NULL){
if(!isPresent(result, t2->data));
^^^^
insertAtBeg(&result,t2->data);
t2 = t2->next;
}
Remove the semicolon.
Also after this call
printList(intersection);
output the new line character like for example
putchar( '\n' );
Pay attention to that you should declare parameters that denotes pointers to nodes with qualifier const if lists are not changed within functions as for example
int isPresent( const node *temp, int ele){
const node *t = temp;
while(t != NULL){
if(t->data == ele)
return 1;
t = t->next;
}
return 0;
}
void printList(const node *n){
while(n != NULL){
printf("%d->",n->data);
n = n->next;
}
}
node* getUnion( const node *head1,const node *head2){
node *result = NULL;
const node *t1 = head1;
const node *t2 = head2;
while(t1 != NULL){
insertAtBeg(&result, t1->data);
t1 = t1->next;
}
while(t2!=NULL){
if(!isPresent(result, t2->data))
insertAtBeg(&result,t2->data);
t2 = t2->next;
}
return result;
}
node *getIntersection(const node *head1,const node *head2){
node* result = NULL;
const node* t1 = head1;
while(t1 != NULL){
if(isPresent(head2, t1->data))
insertAtBeg(&result,t1->data);
t1 = t1->next;
}
return result;
}

Related

How to find the union and intersection of linked lists of strings?

I have tried to code the union and intersection of the 2 linked lists. However, I'm unsuccessful in creating the linked list of strings as its function fails to display and also insert nodes into the list. The code is only able to read the strings of linked list 1. I would want to know the approach to creating a linked list of strings.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
char* data;
struct node *next;
} NODE;
NODE* create(char* data){
NODE* newnode = (NODE*)malloc(sizeof(NODE));
newnode->data = data;
newnode->next = NULL;
return newnode;
}
void insertAtBeg(NODE **head, char* data){
NODE *newnode = create(data);
newnode->data = data;
newnode->next = (*head);
(*head) = newnode;
}
void display(NODE *temp){
while(temp != NULL){
printf("%d->",temp->data);
temp = temp->next;
}
}
int isPresent(NODE *head, char* data){
NODE *temp = head;
while(temp != NULL){
if(temp->data == data)
return 1;
temp = temp->next;
}
return 0;
}
NODE* getUnion(NODE* head1, NODE* head2){
NODE* result = NULL;
NODE *t1 = head1;
NODE *t2 = head2;
while(t1 != NULL){
insertAtBeg(&result, t1->data);
t1 = t1->next;
}
while(t2 != NULL){
if(!isPresent(result,t2->data))
insertAtBeg(&result, t2->data);
t2 = t2->next;
}
return result;
}
NODE* getIntersection(NODE *head1,NODE *head2){
NODE* result = NULL;
NODE *t1 = head1;
while(t1 != NULL){
if(isPresent(head2,t1->data))
insertAtBeg(&result,t1->data);
t1 = t1->next;
}
return result;
}
int main(){
NODE* head1 = NULL;
NODE* head2 = NULL;
NODE* intersection = NULL;
NODE* unin = NULL;
int m,n;
char *arr;
printf("Enter the size of the linked list1:\n");
scanf("%d",&m);
printf("Enter the elements:\n");
for(int i = 0; i< m ; i++){
scanf("%s",arr[i]);
insertAtBeg(&head1,arr[i]);
}
printf("\nDisplaying linked list1:\n");
display(head1);
printf("\nEnter the size of linked list 2:\n");
scanf("%d",&n);
printf("\nEnter the elements:\n");
for(int i = 0; i< n ; i++){
scanf("%s",arr[i]);
insertAtBeg(&head2,arr[i]);
}
printf("\nDisplaying linked list2:\n");
display(head2);
unin = getUnion(head1,head2);
intersection = getIntersection(head1,head2);
printf("\nUnion list:\n");
display(unin);
printf("\nIntersection list:\n");
display(intersection);
return 0;
}
Errors:
warning: passing argument 2 of ‘insertAtBeg’ makes pointer from integer without a cast [-Wint-conversion]
84 | insertAtBeg(&head1,arr[i]);
| ~~~^~~
| |
| char
q.c:16:37: note: expected ‘char *’ but argument is of type ‘char’
16 | void insertAtBeg(NODE **head, char* data){
| ~~~~~~^~~~
q.c:94:31: warning: passing argument 2 of ‘insertAtBeg’ makes pointer from integer without a cast [-Wint-conversion]
94 | insertAtBeg(&head2,arr[i]);
| ~~~^~~
| |
| char
q.c:16:37: note: expected ‘char *’ but argument is of type ‘char’
16 | void insertAtBeg(NODE **head, char* data){
Several issues with the code so I made some changes, at minimum, to point out one issue and also placed printf statement to help in debugging (needs to b done as you're iteratively developing the code).
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
char* data;
struct node *next;
} NODE;
NODE* create(char* data){
NODE* newnode = (NODE*)malloc(sizeof(NODE));
newnode->data = data;
newnode->next = NULL;
return newnode;
}
void insertAtBeg(NODE **head, char* data){
printf("<in insertAtBeg(NODE **head, char* data) \n");
NODE *newnode = create(data);
newnode->data = data;
newnode->next = (*head);
(*head) = newnode;
}
void display(NODE *temp){
while(temp != NULL){
printf("%d->",temp->data);
temp = temp->next;
}
}
int isPresent(NODE *head, char* data){
NODE *temp = head;
while(temp != NULL){
if(temp->data == data)
return 1;
temp = temp->next;
}
return 0;
}
NODE* getUnion(NODE* head1, NODE* head2){
NODE* result = NULL;
NODE *t1 = head1;
NODE *t2 = head2;
while(t1 != NULL){
insertAtBeg(&result, t1->data);
t1 = t1->next;
}
while(t2 != NULL){
if(!isPresent(result,t2->data))
insertAtBeg(&result,t2->data);
t2 = t2->next;
}
return result;
}
NODE* getIntersection(NODE *head1,NODE *head2){
NODE* result = NULL;
NODE *t1 = head1;
while(t1 != NULL){
if(isPresent(head2,t1->data))
insertAtBeg(&result, t1->data);
t1 = t1->next;
}
return result;
}
int main(){
NODE* head1 = NULL;
NODE* head2 = NULL;
NODE* intersection = NULL;
NODE* unin = NULL;
int m,n;
char *arr;
NODE* result = NULL;
insertAtBeg(&head2,&arr[0]);
insertAtBeg(&result, "c"); // t1->data); was data allocated memory?
/*
printf("Enter the size of the linked list1:\n");
scanf("%d",&m);
printf("Enter the elements:\n");
for(int i = 0; i< m ; i++){
scanf("%s",arr[i]);
insertAtBeg(&head1,arr[i]);
}
printf("\nDisplaying linked list1:\n");
display(head1);
printf("\nEnter the size of linked list 2:\n");
scanf("%d",&n);
printf("\nEnter the elements:\n");
for(int i = 0; i< n ; i++){
scanf("%s",arr[i]);
insertAtBeg(&head2,arr[i]);
}
printf("\nDisplaying linked list2:\n");
display(head2);
unin = getUnion(head1,head2);
intersection = getIntersection(head1,head2);
printf("\nUnion list:\n");
display(unin);
printf("\nIntersection list:\n");
display(intersection);
*/
return 0;
}
Output:
<in insertAtBeg(NODE **head, char* data)
<in insertAtBeg(NODE **head, char* data)

make a list of m nodes, where m is taken in input

Hi this is the code I wrote for create as many nodes as he needs (the m variable), but I noticed that using this method I'm creating one more node. What's the best way of fcreating as many nodes as the user say us?
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int val;
int rip;
struct Node *next;
} node;
node *modify(node *head);
void print(node *head2);
int main(){
int m, i;
printf("How many nodes: \n");
scanf("%d", &m);
node *head = NULL;
head = (node *)malloc(sizeof(node));
node *temp = head;
node *head2 = NULL;
printf("Write the value in HEAD position : \n");
scanf("%d", &temp->val);
temp->rip=0;
temp->next = NULL;
for(i=0; i < m-1; i++)
{
temp->next = (node *)malloc(sizeof(node));
printf("Write the value in position %d: \n", i);
temp = temp->next;
scanf("%d", &temp->val);
temp->rip=0;
temp->next = NULL;
}
head2 = modify(head);
print(head2);
return 0;
}
node *modify(node *head){
int counter, pass, m;
node *curr = head;
node *track = head;
node *precNode;
while (track != NULL){
counter = 0;
pass = 0;
m = track->val;
while( curr != NULL){
if(m == (curr)->val){
pass++;
counter++;
if(pass > 1){
node *removed = curr;
precNode->next = (curr)->next;
curr = (curr)->next;
free(removed);
}
if(pass == 1)
{
precNode = curr;
curr = curr->next;
}
}
else{
precNode = curr;
curr = (curr)->next;
}
}
track->rip = counter;
track = track->next;
curr = track;
}
return head;
}
void print(node *head2){
while(head2 != NULL){
printf("[%d, %d] -> ", head2->val, head2->rip);
head2 = head2->next;
}
printf("\n");
}
```

C Linked List Add Item at the End

I'm writing a program that adds a node at the end of an existing linked list.
The problem is that it doesn't seem to assign to the variable nr of struct node of the last element of the linked list the hard coded value 7.
Here is the code:
#include<stdio.h>
#include<stdlib.h>
struct node {
int nr;
struct node *next;
};
void addNodes(struct node **head, int n);
void displayList(struct node *head);
void addItemLast(struct node *head);
int main() {
struct node* head = NULL;
int n;
printf("Introduceti numarul de noduri: ");
scanf("%d", &n);
addNodes(&head, n);
displayList(head);
addItemLast(head);
displayList(head);
return 0;
}
void addNodes(struct node **head, int n) {
*head = (struct node*)malloc(sizeof(struct node));
struct node *current = *head;
printf("\nIntroduceti %d noduri:\n", n);
for(int i = 0; i < n; i++) {
printf("Element %d = ", i+1);
scanf("%d", &(current -> nr));
current->next = (struct node*)malloc(sizeof(struct node));
current = current->next;
}
current->next = NULL;
}
void displayList(struct node *head) {
struct node *current = head;
int i = 1;
printf("\nElementele introduse sunt:\n");
while(current->next != NULL) {
printf("Elementul %d = %d\n", i, current->nr);
current = current->next;
i++;
}
}
void addItemLast(struct node *head) {
struct node *temp = head, *last;
last = (struct node*)malloc(sizeof(struct node));
if(last == NULL) {
printf("\nMemory cannot be allocated!\n");
} else {
last->nr = 7;
last->next = NULL;
while(1) {
if(temp->next == NULL) {
temp->next = last;
break;
}
temp = temp->next;
}
}
}
The last function, addItemLast(), doesn't work as expected.
This is the output:
Introduceti numarul de noduri: 3
Introduceti 3 noduri:
Element 1 = 1
Element 2 = 2
Element 3 = 3
Elementele introduse sunt:
Elementul 1 = 1
Elementul 2 = 2
Elementul 3 = 3
After the function with the problem runs, I get this output:
Elementele introduse sunt:
Elementul 1 = 1
Elementul 2 = 2
Elementul 3 = 3
Elementul 4 = 13383248
Element 4 does not contain the hard coded value 7, but instead has a garbage value and I can't figure out why.
Your implemenation of addNodes is incorrect, suppose I enter n = 2 , 3 nodes are created but only twice scanf function is called, so as result you have garbage value in some node (nr is not set).
Reimplement it (it works if addItemLast function is properly implemented) :
void addNodes(struct node **head, int n){
printf("\nIntroduceti %d noduri:\n", n);
for(int i = 0; i < n; i++){
struct node* last = addItemLast(*head);
if (*head == NULL)
*head = last;
printf("Element %d = ", i);
scanf("%d", &(last -> nr));
}
}
You need to change addItemLast to handle case when you want to call this function but head is NULL (without testing this case your program crashes while calling addItemLast for empty List):
struct node* addItemLast(struct node *head){
struct node *temp = head, *last;
last = (struct node*)malloc(sizeof(struct node));
if (head == NULL) // <---------
{
last->nr = 7;
last->next = NULL;
return last;
}
if(last == NULL){
printf("\nMemory cannot be allocated!\n");
}else{
last->nr = 7;
last->next = NULL;
while(1){
if(temp->next == NULL){
temp->next = last;
break;
}
temp = temp->next;
}
}
return last;
}
and finally function to display list should be:
void displayList(struct node *head){
struct node *current = head;
int i = 1;
printf("\nElementele introduse sunt:\n");
while(current != NULL){ // <---------
printf("Elementul %d = %d\n", i, current->nr);
current = current->next;
i++;
}
}
You do not have to check if current->next != NULL when accessing the element of current.
Change your while loop to:
while(current != NULL){
printf("Elementul %d = %d\n", i, current->nr);
current = current->next;
i++;
}

sorting a singly linked list with quicksort after user input and then inserting a new node and resorting list

I have my code for the most part but having a rough go of it trying to get my quick sort function to work and sort through the actual link list created. Don't know if I am calling the function improperly or if I have the struct correct.
The program will compile and run up until it gets to the calling function for the quicksort. Then it just freezes and does nothing. Any help would be great. Thank you a head of time.
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *link_list;
};
struct node *insertion(struct node *pointer, int i){
struct node *temp_val;
if(pointer == NULL){
pointer = (struct node *)malloc(sizeof(struct node));
if(pointer == NULL){
printf("Error Exiting\n");
exit(0);
}
pointer->data = i;
pointer->link_list = pointer;
}else{
temp_val = pointer;
while(temp_val->link_list != pointer){
temp_val = temp_val->link_list;
}
temp_val->link_list = (struct node *)malloc(sizeof(struct node));
if(temp_val->link_list == NULL){
printf("Error Exiting\n");
exit(0);
}
temp_val = temp_val->link_list;
temp_val->data = i;
temp_val->link_list = pointer;
}
return(pointer);
};
struct node *findPivot(struct node *head, struct node *term, struct node **newHead, struct node **newTerm){
struct node *pivot = term;
struct node *previous = NULL, *current = head, *tail = pivot;
//finding the pivot and dividing the list while also updating the head and term
// with newHead and newTerm
while(current != pivot){
if(current->data < pivot->data){
//assigning the newHead to the first value less then the pivot
if((*newHead) == NULL){
(*newHead) = current;
}
previous = current;
current = current->link_list;
}else{
// if the current node has a higher value then the pivot
// assinging it to newTerm
if(previous){
previous->link_list = current->link_list;
}
struct node *temp = current->link_list;
current->link_list = NULL;
tail->link_list = current;
tail = current;
current = temp;
}
}
//Checks the case if the pivot is the smallest value and moves to head
if((*newHead)== NULL){
(*newHead) = pivot;
}
(*newTerm) = tail; // makes sure the last element is newEnd
return pivot;
}
//finds the last node in the list and returns it
struct node *getTail(struct node *current){
while(current != NULL && current->link_list != NULL){
current = current->link_list;
}
return current;
}
// the actual recursive quicksort algorithm
struct node *quickSort(struct node *head, struct node *term){
if(!head || head == term) //base case for the recursion
return head;
struct node *newHead = NULL, *newTerm = NULL;
// the recursive case
struct node *pivot = findPivot(head, term, &newHead, &newTerm);
//no need for recursion if pivot is smallest value
if(newHead != pivot){
struct node *temp = newHead;
while(temp->link_list != pivot){
temp = temp->link_list;
}
temp->link_list = NULL;
newHead = quickSort(newHead, temp);
temp = getTail(newHead);
temp->link_list = pivot;
}
pivot->link_list = quickSort(pivot->link_list, newTerm);
return newHead;
}
void quickSortFunction(struct node **pointer){
*pointer = quickSort(*pointer, getTail(*pointer));
return;
}
void printList_Unsorted(struct node *pointer){
struct node *temp;
temp = pointer;
printf("\nThe Data values in the list are:\n");
if(pointer != NULL){
do{
printf("%d\t", temp->data);
temp = temp->link_list;
}while(temp != pointer);
}else{
printf("the list is empty\n");
}
}
void printList_Sorted(struct node *node){
while(node!= NULL){
printf("%d ", node->data);
node = node->link_list;
}
printf("\n");
}
int main(int argc, char *argv[]) {
int num_nodes, node_val;
struct node *list = NULL;
printf("Enter the number of nodes to be created: ");
scanf("%d", &num_nodes);
while(num_nodes --> 0){
printf("\n\nEnter the data values to be placed in a node: ");
scanf("%d", &node_val);
list = insertion(list, node_val);
}
printf("\n\nThe Created list is as follow:\n");
printList_Unsorted(list);
printf("\n");
quickSortFunction(&list);
printList_Sorted(list);
//getchar();
//getchar();
return 0;
}
Please look at this working example.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *link_list;
};
void insertion(struct node **pointer, int i) {
struct node *temp_val = malloc(sizeof *temp_val);
temp_val->data = i;
temp_val->link_list = (*pointer);
(*pointer) = temp_val;
}
/* A utility function to print linked list */
void printList(struct node *node) {
while (node != NULL) {
printf("%d ", node->data);
node = node->link_list;
}
printf("\n");
}
// Returns the last node of the list
struct node *getTail(struct node *current) {
while (current != NULL && current->link_list != NULL)
current = current->link_list;
return current;
}
struct node *findPivot(struct node *head, struct node *term,
struct node **newHead, struct node **newTerm) {
struct node *pivot = term;
struct node *previous = NULL, *current = head, *tail = pivot;
while (current != pivot) {
if (current->data < pivot->data) {
if ((*newHead) == NULL)
(*newHead) = current;
previous = current;
current = current->link_list;
}
else
{
if (previous)
previous->link_list = current->link_list;
struct node *tmp = current->link_list;
current->link_list = NULL;
tail->link_list = current;
tail = current;
current = tmp;
}
}
// If the pivot data is the smallest element in the current list,
// pivot becomes the head
if ((*newHead) == NULL)
(*newHead) = pivot;
// Update newTerm to the current last node
(*newTerm) = tail;
// Return the pivot node
return pivot;
}
// the actual recursive quicksort algorithe
struct node *quickSort(struct node *head, struct node *end) {
// base case
if (!head || head == end)
return head;
struct node *newHead = NULL, *newEnd = NULL;
struct node *pivot = findPivot(head, end, &newHead, &newEnd);
if (newHead != pivot) {
struct node *tmp = newHead;
while (tmp->link_list != pivot)
tmp = tmp->link_list;
tmp->link_list = NULL;
newHead = quickSort(newHead, tmp);
tmp = getTail(newHead);
tmp->link_list = pivot;
}
pivot->link_list = quickSort(pivot->link_list, newEnd);
return newHead;
}
void quickSortFunction(struct node **headRef) {
(*headRef) = quickSort(*headRef, getTail(*headRef));
return;
}
int main() {
struct node *list = NULL;
int num_nodes, node_val;
printf("Enter the number of nodes to be created: ");
scanf("%d", &num_nodes);
while(num_nodes --> 0){
printf("\n\nEnter the data values to be placed in a node: ");
scanf("%d", &node_val);
insertion(&list, node_val);
}
printf("\n\nThe Created list is as follows:\n");
printList(list);
printf("\n");
quickSortFunction(&list);
printList(list);
return 0;
}
Test
/home/dac/.CLion2016.2/system/cmake/generated/gnu-fadf49ce/fadf49ce/Debug/gnu
Enter the number of nodes to be created: 3
Enter the data values to be placed in a node: 2
Enter the data values to be placed in a node: 4
Enter the data values to be placed in a node: 3
The Created list is as follows:
3 4 2
2 3 4
Process finished with exit code 0
The problem with your code was that it entered an infinite loop because the parameter was not a pointer to the node, but a pointer to the struct. You also don't need to return the list because you are passing it by reference.

Sorting a linked list in C

I'm trying to sort a linked list by finding the largest value, deleting it from its position, and then inserting it at the top of the list.
The difficulty I'm running into is the actual deleting and inserting at the top. The issue seems to be in the if condition in the while loop contained within the sortList function, but I'm not sure how to fix it.
Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int num;
struct node *next;
} Node, *NodePtr;
void printList(NodePtr np);
NodePtr makeList(void);
NodePtr makeNode(int n);
NodePtr sortList(NodePtr list);
int main(void) {
NodePtr list;
printf("Enter numbers for the list (0 to end)\n");
list = makeList();
printList(list);
list = sortList(list);
printList(list);
return 0;
}
NodePtr makeList(void) {
NodePtr makeNode(int), np, top, last;
int n;
top = NULL;
if(scanf("%d", &n) != 1)n = 0;
while(n != 0) {
np = makeNode(n);
if(top == NULL)top = np;
else last->next = np;
last = np;
if(scanf("%d", &n)!=1)n=0;
}
return top;
}
void printList(NodePtr np) {
while(np != NULL) {
printf("%d\n", np->num);
np = np->next;
}
}
NodePtr makeNode(int n) {
NodePtr np = (NodePtr)malloc(sizeof(Node));
np->num = n;
np->next = NULL;
return np;
}
NodePtr sortList(NodePtr list) {
NodePtr top = list;
NodePtr curr = NULL;
NodePtr largest;
NodePtr prev;
prev = NULL;
curr = top;
largest = top;
while(curr != NULL) {
prev = curr;
if(curr->num > largest->num) {
largest = curr;
prev->next = curr->next;
largest->next = top;
}
curr = curr->next;
}
if(prev == NULL) {
largest->next = top;
return largest;
}
return largest;
}
There is issues in the sortList function.
This function only put some large nodes in the beginning of the list. It is not soting all the list. you can you a sort algorithm to sort the file : quicksort/ bubblesort/...
i put a code doing a sort in the end of this answer.
here is a code doing the sort of the list :
//it is replacing largest node with first one then doing the same operation with sublist (list-first element)
NodePtr sortList(NodePtr list)
{
//
if(list == null || list->next == null)
return list; // the list is sorted.
//replace largest node with the first :
//1- find largest node :
NodePtr curr, largest,largestPrev;
curr = list;
largest = list;
prev = list;
largestPrev = list;
while(curr != NULL) {
if(curr->num > largest->num) {
largestPrev = prev;
largest = curr;
}
prev = curr;
curr = curr->next;
}
//largest node is in largest.
//2- switching firt node and largest node :
NodePtr tmp;
if(largest != list)
{
largestPrev->next = list;
tmp = list->next;
list->next = largest->next;
largest->next = tmp;
}
// now largest is the first node of the list.
// calling the function again with the sub list :
// list minus its first node :
largest->next = sortList(largest->next);
return largest;
}
Here is my attempt to sort a singly linked list using QuickSort algorithm. If you know n then run time will be O(n log n). Check if this helps.
#include "malloc.h"
typedef struct node {
struct node *next;
int val;
} node;
bool insert_node(struct node **head, int val)
{
struct node *elem;
elem = (struct node *)malloc(sizeof(struct node));
if (!elem)
return false;
elem->val = val;
elem->next = *head;
*head = elem;
return true;
}
int get_lval(struct node *head, int l)
{
while(head && l) {
head = head->next;
l--;
}
if (head != NULL)
return head->val;
else
return -1;
}
void swap(struct node *head, int i, int j)
{
struct node *tmp = head;
int tmpival;
int tmpjval;
int ti = i;
while(tmp && i) {
i--;
tmp = tmp->next;
}
tmpival = tmp->val;
tmp = head;
while(tmp && j) {
j--;
tmp = tmp->next;
}
tmpjval = tmp->val;
tmp->val = tmpival;
tmp = head;
i = ti;
while(tmp && i) {
i--;
tmp = tmp->next;
}
tmp->val = tmpjval;
}
struct node *Quick_Sort_List(struct node *head, int l, int r)
{
int i, j;
int jval;
int pivot;
i = l + 1;
if (l + 1 < r) {
pivot = get_lval(head, l);
printf("Pivot = %d\n", pivot);
for (j = l + 1; j <= r; j++) {
jval = get_lval(head, j);
if (jval < pivot && jval != -1) {
swap(head, i, j);
i++;
}
}
swap(head, i - 1, l);
Quick_Sort_List(head, l, i);
Quick_Sort_List(head, i, r);
}
return head;
}
struct node *Sort_linkedlist(struct node *head)
{
struct node *tmp = head;
// Using Quick sort.
int n = 0;
while (tmp) {
n++;
tmp = tmp->next;
}
printf("n = %d\n", n);
head = Quick_Sort_List(head, 0, n);
return head;
}
void print_list(struct node *head)
{
while(head) {
printf("%d->", head->val);
head = head->next;
}
printf("\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
struct node *head = NULL;
struct node *shead = NULL;
insert_node(&head, 10);
insert_node(&head, 12);
insert_node(&head, 9);
insert_node(&head, 11);
insert_node(&head, 7);
insert_node(&head, 1);
insert_node(&head, 3);
insert_node(&head, 8);
insert_node(&head, 5);
insert_node(&head, 2);
insert_node(&head, 4);
insert_node(&head, 6);
print_list(head);
shead = Sort_linkedlist(head);
print_list(shead);
return 0;
}
By writing to largest->next you overwrote curr->next. So you end up restarting from the top all the time.
Make sure that:
the list remains consistent
your list iterator remains consistent
But overall, your code seems to be heavily broken, I believe there might be a couple other errors in your sorting logic.
The following are some of the problems which exist in your sorting logic:
You are setting the prev pointer to curr in the beginning of the loop itself which is incorrect. By doing this, you are making the current pointer and the previous node pointer as same which makes it impossible to delete the node.
You should assign the largest pointer also to top whereby it facilitates the possibility of setting the largest->next to real top node.
The code can modified like below (Just a pointer, you need to check for other issues yourself):
while(curr != NULL)
{
if(curr->num > largest->num)
{
largest = curr;
prev->next = curr->next;
largest->next = top;
top = largest;
}
prev = curr;
curr = curr->next;
}
// Program to sort a single linked list in ascending order
// (without exchanging data in the nodes)
/**************************************************************************
There are two methods of sorting presented here(At a time,we can use any of
these two functions to sort our single linked list.) -
1. Function 'void Sort()' - This function uses selection sort method(I
think).
In this function,a node whose data is the smallest in the list is made
as 'head' node(i.e. starting node of the list) by scanning the whole list
once.Then from the remaining list,again a node with the smallest data is
found out whose address is kept in the 'next' field of previous node(head
node).This process continues to sort the whole list.
2. Function 'void Sort_method2()' - This function uses insertion sort
method(I think).
In this function,starting from second node in the list, all previous node
data(starting from 'head' node) are compared with current reference node
(which is initially second node in the list).If 'data' field of current
reference node is smaller than that of any of its previous nodes,then
suitable changes in the 'next' field of corresponding nodes are made.If
data in the current reference node is smaller than that in the 'head' node,
then the current reference node is made as 'head' node.
*********************************************************************/
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head,*head1;
void Create_node(int data);
void display();
void Sort();
void Sort_method2();
void main()
{
int choice,d;
clrscr();
while(1)
{
printf("\n 1.Create new node");
printf("\n 2.Sort in ascending order");
printf("\n 3.Exit");
printf("\nEnter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("\nEnter data :");
scanf("%d",&d);
Create_node(d);
break;
case 2: Sort(); // At a time,we can use any of these two
//Sort_method2(); // functions to sort our single linked list.
break;
case 3: exit(0);
default:exit(0);
}
} // end of while(1)
} // end of main()
//--------------------------------------------
void Create_node(int d)
{
struct node *newnode,*temp;
newnode = (struct node *)malloc(sizeof(struct node));
newnode -> data = d;
newnode -> next = NULL;
if(head == NULL)
head = newnode;
else
{
temp = head;
while(temp -> next != NULL)
temp = temp -> next;
temp -> next = newnode;
} // end of 'else'
} // end of 'Create_node(int d)'
//---------------------------------------------
void display() // Print linked list contents
{
struct node *temp;
printf("\nList contents are :\n");
temp = head;
while(temp != NULL)
{
printf(" Data = %d Address = %u\n",temp->data,temp);
temp = temp->next;
}
printf("\n");
}
//--------------------------------------------
void Sort()
{
struct node *t,*t1,*t2,*t3;
t1 = head;
head1 = head;
if(head == NULL)
printf("\nThe linked list is empty!");
else
{
while( (t2 = t1 -> next) != NULL)
{
while(t2 != NULL)
{
t3 = t2 -> next;
if( t1 -> data > t2 -> data)
{
t2 -> next = t1;
for(t = t1; t -> next != t2;t = t -> next);
t -> next = t3;
t1 = t2; // t1 = Node with smaller data
t2 = t3; // t2 = Node to be compared with t1
} // end of 'if'
else
{
// t1 = t1; // That is,no change in t1.
t2 = t3;
}
} // end of ' while(t2 != NULL)'
if(head == head1) // We want this action only for first pass of
{ // outer while() loop.Only initially, head = head1.
head = t1;
head1 = t1 -> next;
} // end of 'if(head == head1)'
else
{
for(t = head;t -> next != head1; t = t -> next);
t -> next = t1;
head1 = t1 -> next;
} // end of 'else'
t1 = t1 -> next;
} // end of 'while( (t2 = t1 -> next) != NULL)'
display(); // Display the list.
} // end of 'else' of 'if(head == NULL)'
} // end of 'Sort()'
//--------------------------------------------
void Sort_method2()
{
struct node *t,*t1,*t2,*tt;
if(head == NULL)
printf("\nThe linked list is empty!");
else
{
t1 = head -> next;
while(t1 != NULL) // This is i-loop(outer loop).
{
t2 = t1 -> next;
for(t = head; t != t1; t = t -> next) // This is j-loop(inner loop).
{
if(t1->data < t->data)
{
t1 -> next = t;
for(tt=head; tt->next != t1; tt=tt->next); //end of for loop in 'if'
tt -> next = t2;
if(t == head)
head = t1; // There is only one statement in this 'if'.
else // i.e.,'if(t != head)'
{
for(tt=head; tt->next != t; tt=tt->next);
tt -> next = t1;
}
break;
} // end of 'if'
} // end of outer 'for' loop
t1 = t2;
} // end of 'while'
display(); // Display the list.
} // end of 'else' of 'if(head == NULL)'
} // end of 'Sort_method2()'

Resources