Sorting a linked list in C - 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()'

Related

Polynominal with doubly linked list - pointer problem

I made some polynomial code with a doubly-linked list. for example, if
you write 1 and 2 then 1 is a degree and 2 is coefficient. 1x^2 insert
to doubly linked list. the problem is that when I check my code, the Node
head->degree is changing. if I write 1x^2 then head->degree is 1 next,
I write 2x^1 then head-> degree should maintain 1 but head-> degree
change to 2 I think there is some problem in the head pointer.
#include <stdio.h>
#include <stdlib.h>
// struct
struct Node {
int degree;
int coefficient;
struct Node* next;
struct Node* prev;
};
// global variables
int de; // degree
int co; // coefficient
int flag;
Node** head = (Node**)malloc(sizeof(Node)); //
Node** head1 = (Node**)malloc(sizeof(Node)); //
Node** head2 = (Node**)malloc(sizeof(Node)); //
Node** head3 = (Node**)malloc(sizeof(Node)); //
Node* newNode = (Node*)malloc(sizeof(Node)); //
// function
Node* inputpoly(void);
void printNode(Node* inp);
Node* multiply(Node* a, Node* b);
// main
int main() {
// head null
(*head1) = NULL;
(*head2) = NULL;
(*head3) = NULL;
while (1) {
printf("Input (degree) (coefficient) : ");
scanf_s("%d %d", &de, &co);
if (de * co < 0) { continue; }
if (de < 0 && co < 0) {
printf("Done!\n");
break;
}
*head = inputpoly();
}
printNode(*head);
//multiply(*head1, *head2);
free(head1);
free(head2);
free(head3);
free(newNode);
free(head);
}
Node* inputpoly(void) {
// create Node
newNode->degree = de;
newNode->coefficient = co;
newNode->next = NULL;
newNode->prev = NULL;
// case1
if (flag == 0) {
// list
if ((*head1) == NULL) {
*head1 = newNode;
}
// list x
else {
Node* horse = (*head1);
// front of head
// ------------------There is some problem
printf("%d\n", 1);
printf("--%d\n", newNode->degree);
printf("--%d\n", horse->degree);
if (horse->degree > newNode->degree) {
newNode->next = horse;
horse->prev = newNode;
*head1 = newNode;
}
// barward of head
else {
int num = 0;
while (horse->next != NULL) {
horse = horse->next;
if (horse->degree > newNode->degree) {
horse->prev->next = newNode;
newNode->next = horse;
newNode->prev = horse->prev;
horse->prev = newNode;
num = 1;
break;
}
}
// behind tail
if (num == 0) {
horse->next = newNode;
newNode->prev = horse;
}
}
}
return *head1;
}
}
void printNode(Node* inp) {
Node* horse = inp;
if (horse == NULL)
{
return;
}
while (horse != NULL) {
if (horse->prev == NULL) {
if (horse->degree == 1) {
printf("%d", horse->coefficient);
}
else {
printf("%d x^%d", horse->coefficient, horse->degree);
}
}
else {
if (horse->degree == 1) {
printf(" + %d", horse->coefficient);
}
else {
printf(" + %d x^%d", horse->coefficient, horse->degree);
}
}
}
printf("\n");
}
"i think there is some head pointer problem, and if I fixed it I can this problem. so I want to maintain this code as possible. I want some
advice or solution to my head pointer"
The code posted in your example does not compile:
Before you can fix a head pointer problem the code must compile. This list of errors is detailing 2 things:
first, functions cannot be called outside of a function, eg:
Node** head = (Node**)malloc(sizeof(Node)); //
Node** head1 = (Node**)malloc(sizeof(Node)); //
Node** head2 = (Node**)malloc(sizeof(Node)); //
Node** head3 = (Node**)malloc(sizeof(Node)); //
Node* newNode = (Node*)malloc(sizeof(Node)); //
should be called from within main(void){...} or some other function.
second, every occurrence of Node should be prepended with struct. eg:
struct Node** head = malloc(sizeof(struct Node *));
(have also removed the cast, and modified the size of what you are creating memory for, i.e. a pointer)
Rather then fix these and other problems, here is an example of a doubly linked list that can demonstrate the structure of a simple working program. You can adapt the following to match your needs:
struct Node {
int deg;
int coef;
struct Node* next; // Pointer to next node in DLL
struct Node* prev; // Pointer to previous node in DLL
};
void inputpoly(struct Node** head_ref, int deg, int coef)
{
//allocate node
struct Node *new_node = malloc(sizeof(*new_node));
//assign data
new_node->deg = deg;
new_node->coef = coef;
//set next as new head and prev to null
new_node->next = (*head_ref);
new_node->prev = NULL;
//change prev of head to new */
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
//point head to the new node */
(*head_ref) = new_node;
}
void printList(struct Node* node)
{
struct Node* last;
printf("\nread forward\n");
while (node != NULL) {
printf(" %d,%d ", node->deg,node->coef);
last = node;
node = node->next;
}
printf("\nread reverse\n");
while (last != NULL) {
printf(" %d,%d ", last->deg,last->coef);
last = last->prev;
}
}
int main(void)
{
//start with empty list
struct Node* head = NULL;
//create and populate new nodes
inputpoly(&head, 7, 2);
inputpoly(&head, 1, 4);
inputpoly(&head, 4, 6);
//ouput list
printList(head);
getchar();
return 0;
}
Note that this code is offered as a basic demonstration of creating doubly linked list, and illustrate how to traverse both directions. Because it does not free allocated memory, it is not recommended that it be used for any production purpose without addressing that omission.

Problem in understanding some basic linked list function

void
LInsert (LIST * l, int x, int pos)
{
struct Node *new, *p; // p: previous node
// create a new node
new = (struct Node *) malloc (sizeof (struct Node));
new->val = x;
if (pos == 0)
{ // insert to start
new->next = l->head;
l->head = new;
}
else
{
// insert after p
p = l->head;
while (p != NULL && pos > 1)
{
p = p->next;
--pos;
}
if (p == NULL)
{
printf ("LInsert: Position not possible\n");
return;
}
new->next = p->next;
p->next = new;
}
l->size++;
}
This is a function of inserting a node to a linked list. I don't understand a few lines in this program.
In the first if condition there is a line new->next=l->head; From my thinking it means that in the "next" part of the new node it will store the what's in the head node(an address probably), but why?. It makes the linked list a circular linked list but this is just a simple linked list.
Also near the end new->next=p->next what does this mean.It makes the linked list circular again.
Hope the indentation is correct I always get people yelling at me for wrong indentation
Here is the complete code which includes struc declaration and stuff
#include <stdio.h>
#include <stdlib.h>
struct Node {
int val;
struct Node *next;
};
struct List {
struct Node *head;
int size;
};
// LIST is new name for "struct List"
typedef struct List LIST;
void LInit(LIST *l){ // Initialize list to empty
l->head = NULL; // pointer to first node
l->size = 0; // number of nodes
}
int LGetPos(LIST *l, int x) {
struct Node *p;
int i=0;
// go through all nodes
for (p=l->head; p!=NULL; p=p->next)
if (p->val == x) return i; // found
else i++; // next
return -1; // not found in the list
}
int LGetAt(LIST *l, int pos) {
struct Node *p=l->head;
int i;
// go to position
for(i=0; p!=NULL && i<pos; i++) p = p->next;
if(p) return p->val; // if exists, return it
else { printf("LDelete: Position not exist\n"); return -99; }
}
void LInsert(LIST *l, int x, int pos) {
struct Node *new, *p; // p: previous node
// create a new node
new = (struct Node *) malloc(sizeof(struct Node));
new->val = x;
if(pos==0) { // insert to start
new->next = l->head;
l->head = new;
}
else { // insert after p
p = l->head;
while(p!=NULL && pos>1) { p = p->next; --pos; }
if(p==NULL) { printf("LInsert: Position not possible\n"); return; }
new->next = p->next;
p->next = new;
}
l->size++;
}
void LDelete(LIST *l, int pos) {
struct Node *p, *d; // p: previous
if(l->head == NULL) return;
if(pos==0) { // delete first node
d = l->head;
l->head = d->next;
}
else { // delete after p
p = l->head;
while(pos>1 && p) { p = p->next; --pos; }
if(p==NULL) { printf("LDelete: Position not exist\n"); return; }
d = p->next;
p->next = p->next->next;
}
l->size--;
free(d);
}
int LIsEmpty(LIST * l){
return (l->size == 0);
}
int LSize(LIST * l){
return (l->size);
}
void LDisplay(LIST *l) {
struct Node *p;
printf("List: ");
for(p=l->head; p!=NULL; p=p->next)
printf("--> %d ", p->val);
printf("\n");
}
int LHeadOf(LIST *l) {
if (!LIsEmpty(l)) return l->head->val;
else {
printf("LHeadOf: Linked list empty\n");
return -99;
}
}
int main() {
LIST list;
LInit(&list);
LDisplay(&list);
LInsert(&list, 3, 0);
LInsert(&list, 4, 0);
LInsert(&list, 5, 2);
LDisplay(&list);
printf("Value at 1: %d\n", LGetAt(&list, 1));
printf("Location of 4: %d\n", LGetPos(&list, 4));
LDelete(&list, 1);
LDisplay(&list);
return 0;
}
I don't understand a few lines in this program
Okay - let's take a look of those lines...
here is a line new->next=l->head; From my thinking it means that in the "next" part of the new node it will store the what's in the head node(an address probably), but why?
That line is used to insert the new element in front of the current head element. So
new->next=l->head; // Make the new element point to current head
l->head = new; // Change head to point to the new element as it is now the front element
Also near the end new->next=p->next what does this mean.It makes the linked list circular again.
Well, it doesn't make the list circular. It simply insert the new element somewhere in the middle of the list.
new->next = p->next; // Make new point to the element after p
p->next = new; // Make p point to new
// In this way new has between inserted after p and
// before the element that folloed p

Memory error while using free function to a linked list

Memory error with freeing a linked list that contains an int and next only.
I have tried the following function that is shown in the beginning of the code.
This program recieves the number of nodes in the linked list and a value for each node. Next, the program asks for the number of rotations (k) for the list and rotate the list k numbers to the left. The function works well until freeing the memory that was allocated.
The error happens in the free(temp) line "Debug error HEAP CORRUPTION DETECTED".
#include <stdio.h>
#include <stdlib.h>
typedef struct IntNode
{
int val;
struct IntNode* next;
} IntNode;
void printList(IntNode* list);
void freeList(IntNode* head);
IntNode* createNode(int val);
void moveKPlaces(IntNode** list, int k);
int numNodes = 0;
int main(void)
{
IntNode* list = NULL;
IntNode* curr = list;
IntNode* newNode = NULL;
int i = 0, num = 0, k = 0;
printf("How many nodes in list? ");
scanf("%d", &numNodes);
getchar();
for (i = 0; i < numNodes; i++)
{
printf("Enter number: ");
scanf("%d", &num);
getchar();
if (i == 0)//head of the list
{
newNode = createNode(num);
list = newNode;
curr = list;
}
else
{
while (curr->next != NULL)
{
curr = curr->next;
}
newNode = createNode(num);
curr->next = newNode;
newNode->next = NULL;
}
}
printf("Choose a number k, and the list will be rotated k places to the left: ");
scanf("%d", &k);
getchar();
printf("The rotated list:\n");
moveKPlaces(&list, k);
printList(list);
freeList(list);
getchar();
return 0;
}
/*
This function recieves a pointer to a pointer to the head of a list and
a number (k) and rotate the list k places to the left.
input:
a pointer to a pointer to the head of a list and
a number (k)
output:
none
*/
void moveKPlaces(IntNode** list, int k)
{
IntNode* curr = *list;
IntNode* last = NULL;
IntNode* head = *list;
int placeNode = 0;
while (curr->next != NULL)
{
curr = curr->next;
}
curr->next = head;//turn it to a circular list
while (placeNode < k)
{
curr = curr->next;
placeNode++;
}
*list = curr->next;// the k node will be the head
curr->next = NULL;// the one before will be the last
}
//************************************
// Method: printList
// Returns: void
// Description: prints list recursively
// Parameter: IntNode * list
//************************************
void printList(IntNode* list)
{
if (list)
{
printf("%d ", list->val);
printList(list->next);
}
else
{
printf("\n");
}
}
void freeList(IntNode* head)
{
IntNode* temp = NULL;
IntNode* curr = head;
while (curr)
{
temp = curr;
curr = (curr)->next;
free(temp);
}
head = NULL;
}
IntNode* createNode(int val)
{
IntNode* newNode = (IntNode*)malloc(sizeof(newNode));//will alocate every person node dinamically
newNode->val = val;
// insert all details
newNode->next = NULL;
return newNode;
}
Expected free without any error
"Debug error HEAP CORRUPTION DETECTED".
IntNode* newNode = (IntNode*)malloc(sizeof(newNode));//will alocate every person node dinamically
That doesn't allocate enough space. It should be sizeof(*newNode) or sizeof(IntNode).

C: Recursive sorting of linked list

I'm trying to implement a recursive sorting algorithm for linked list structure. C language.
My algorithm is this:
1) find max value in list
2) remove it from the list and insert it at Head node
3) start algorithm again from next node
4) run until you reach end of list
I have something, but it doesn't 'remember' my list. I realize I'm making a mistake somewhere (probably recursive calls), but I can't understand how to fix it.
typedef struct Node{
int data;
struct Node* next;
} Node;
void insert(Node** head, int val)
{
//insert at top
Node* to_insert = (Node*)malloc(sizeof(Node));
to_insert->data = val;
to_insert->next = (*head);
(*head) = to_insert;
}
Node* sort_ll(Node* head)
{
//base case, iterated trough entire list
if(head == NULL)
return NULL;
int max = 0;
Node* tmp = head;
Node* to_move = tmp;
//find maximum value
while(tmp != NULL) {
if(tmp->data > max) {
max = tmp->data;
to_move = tmp;
}
tmp = tmp->next;
}
//if its currently top, leave it there
if(to_move == head) {
return sort_ll(head->next);
}
//find node with max value
tmp = head;
while(tmp->next != to_move) {
tmp = tmp->next;
}
//cut it out from the list
tmp->next = tmp->next->next;
free(to_move);
//insert value at the head of the list
insert(&head, max);
return sort_ll(head->next);
}
int main()
{
Node* list = NULL;
insert(&list, 3);
insert(&list, 6);
insert(&list, 7);
insert(&list, 2);
insert(&list, 1);
insert(&list, 5);
insert(&list, 4);
list = sort_ll(list);
Node* tmp = list;
while(tmp != NULL) {
printf("%d\n", tmp->data);
tmp = tmp->next;
}
return 0;
}
fix like this
Node *sort_ll(Node* head){
if(head == NULL || head->next == NULL)
return head;//There is no need for processing
int max = head->data;
Node *prev = head;
Node *to_move = NULL;
Node *tmp = head->next;
//find maximum value in rest(head->next)
while(tmp != NULL) {
if(tmp->data > max) {
max = tmp->data;
to_move = prev;//save previous node for remove link
}
prev = tmp;
tmp = tmp->next;
}
if(to_move == NULL) {//not find in rest
head->next = sort_ll(head->next);
return head;
}
prev = to_move;
to_move = prev->next;//max node
prev->next = prev->next->next;//max node remove from link
to_move->next = sort_ll(head);
return to_move;
}

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.

Resources