Problem in understanding some basic linked list function - c

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

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.

void* in linkedList

i have a simple linked list that looks like this
typedef struct Node {
void *data;
struct Node *next
} Node;
typedef struct Node {
Node *head;
Node *tail;
int size;
} LinkedList
And my add_node function looks like this :
void add_nth_node(LinkedList *list, int n, void *new_data) {
Node *prev, *curr;
Node *new_node;
if (list == NULL) {
return;
}
/* n >= list->size inseamna adaugarea unui nou nod la finalul listei. */
if (n > list->size) {
n = list->size;
} else if (n < 0) {
return;
}
curr = list->head;
prev = NULL;
while (n > 0) {
prev = curr;
curr = curr->next;
--n;
}
new_node = malloc(sizeof(Node));
if (new_node == NULL) {
perror("Not enough memory to add element!");
exit(-1);
}
new_node->data = new_data;
new_node->next = curr;
if (prev == NULL) {
/* Adica n == 0. */
list->head = new_node;
} else {
prev->next = new_node;
}
if (new_node->next == NULL) {
list->tail = new_node;
}
list->size++;
There is something weird when i try to add nodes to the list.
When i add them like this :
int i;
for (i = 0; i < 10; i++) {
add_nth_node(list, i, &i);
}
But when i add elements like this :
int i, v[10];
for(i = 0; i < 10; i++) {
v[i] = i;
add_nth_node(list_1, i, &v[i]);
}
Everything is working as expected. Why is that ?
Why do i have to put elements is a vector first to add them to the list.
add_nth_node(list, i, &i) // (1)
// and
add_nth_node(list_1, i, &v[i]); // (2)
They are not the same but the value of data that you assign for each node is the same in two options.
(1) You make the pointer point to address of i.
(2) You make the pointer point to address of v[i].
Use (1) is very bad idea because, in this case all data of all nodes point to the same address. So if the data of one node changes, the data of all nodes change the value.

competitve programming Dijkstra

can any one tell me where is the error in this program please it will be really helpful , i did my best to solve this problem ,this code is passing only two test cases
Given an undirected graph and a starting node, determine the lengths of the shortest paths from the starting node to all other nodes in the graph. If a node is unreachable, its distance is -1. Nodes will be numbered consecutively from to , and edges will have varying distances or lengths.
Here is the question https://www.hackerrank.com/challenges/dijkstrashortreach/problem
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
// Node
typedef struct node {
int data;
// Lower values indicate higher priority
int priority;
struct node* next;
} Node;
// Function to Create A New Node
Node* newNode(int d, int p)
{
Node* temp = (Node*)malloc(sizeof(Node));
temp->data = d;
temp->priority = p;
temp->next = NULL;
return temp;
}
// Return the value at head
int peek(Node** head)
{
return (*head)->data;
}
// Removes the element with the
// highest priority form the list
void pop(Node** head)
{
Node* temp = *head;
(*head) = (*head)->next;
free(temp);
}
void updateprt(Node** head, int data) {
if ((*head)->data == data)
{
Node* temp = *head;
*head = (*head)->next;
free(temp);
return;
}
Node* prev = *head;
while ((prev->next)->data != data) {
prev = prev->next;
}
Node* start = prev->next;
prev->next = start->next;
free(start);
}
// Function to push according to priority
void push(Node** head, int d, int p)
{
Node* start = (*head);
// Create new Node
Node* temp = newNode(d, p);
if (*head == NULL) {
*head = temp;
return;
}
// Special Case: The head of list has lesser
// priority than new node. So insert new
// node before head node and change head node.
if ((*head)->priority > p) {
// Insert New Node before head
temp->next = *head;
(*head) = temp;
}
else {
// Traverse the list and find a
// position to insert new node
while (start->next != NULL &&
start->next->priority < p) {
start = start->next;
}
// Either at the ends of the list
// or at required position
temp->next = start->next;
start->next = temp;
}
}
// Function to check is list is empty
int isEmpty(Node** head)
{
return (*head) == NULL;
}
struct adjlistnode {
int data;
struct adjlistnode* next;
};
struct adjlist {
struct adjlistnode* head;
};
struct graph {
int v;
struct adjlist* array;
};
struct graph* creategraph(int v) {
struct graph* G = (struct graph*) malloc(sizeof(struct graph));
G->v = v;
int i;
G->array = (struct adjlist*)malloc(sizeof(struct adjlist)*v);
for (i = 0; i < v; i++) {
G->array[i].head = NULL;
}
return G;
}
int Distance[100000], path[50];
struct adjlistnode* getnewnode(int ver) {
struct adjlistnode* newnode = (struct adjlistnode*)malloc(sizeof(struct adjlistnode));
newnode->data = ver;
newnode->next = NULL;
return newnode;
}
void addedge(struct graph* G, int src, int dest, long int w, long int** weight) {
struct adjlistnode* temp;
temp = getnewnode(dest);
temp->next = G->array[src].head;
G->array[src].head = temp;
temp = getnewnode(src);
temp->next = G->array[dest].head;
G->array[dest].head = temp;
if (weight[src][dest] != 0 || weight[dest][src] != 0 && w < weight[src][dest]) {
weight[src][dest] = w;
weight[dest][src] = w;
}
if (weight[src][dest] == 0) {
weight[src][dest] = w;
weight[dest][src] = w;
}
}
void printgraph(struct graph* G) {
for (int i = 0; i < G->v; i++) {
struct adjlistnode* temp = G->array[i].head;
printf("%d-> ", i);
while (temp) {
printf(" %d", temp->data);
temp = temp->next;
}
printf("\n");
}
}
void Dijkstra(Node** queue, struct graph* G, int s, long int** weight) {
int v, w, d;
push(queue, s, 0);
for (int i = 0; i < 100000; i++) {
Distance[i] = -1;
}
Distance[s] = 0;
while (!isEmpty(queue)) {
v = peek(queue);
pop(queue);
struct adjlistnode* temp = G->array[v].head;
while (temp) {
w = temp->data;
d = Distance[v] + weight[v][w];
//To update the distance of w check the below two conditions
if (Distance[w] == -1) {
Distance[w] = d;
push(queue, w, d);
path[w] = v;
}
if (Distance[w] > d)
{
Distance[w] = d;
path[w] = v;
updateprt(queue, w);
push(queue, w, d);
}
temp = temp->next;
}
}
}
int main()
{
int t;
scanf("%d", &t);
while (t) {
Node* pq = NULL;
int v;
int e;
scanf("%d %d", &v, &e);
long int** weight = (long int**)malloc(sizeof(long int*)*v);
for (int i = 0; i < v; i++)
weight[i] = (long int*)malloc(sizeof(long int)*v);
struct graph* G = creategraph(v);
int u, w;
long int l;
for (int i = 0; i < e; i++) {
scanf("%d %d %ld", &u, &w, &l);
addedge(G, u - 1, w - 1, l, weight);
}
int s;
scanf("%d", &s);
// printgraph(G);
//printf("\n");
Dijkstra(&pq, G, s - 1, weight);
for (int i = 0; i < G->v; i++) {
if (i == s - 1)
continue;
printf("%d ", Distance[i]);
}
/* while (!isEmpty(&pq)) {
printf("%d ", peek(&pq));
pop(&pq);
}*/
return 0;
}
system("pause");
}
Your biggest issue is with your priority queue, which you implement as simple linked list. You seem to be confused about when and how to use a pointer to node pointer.
For example, this function:
int isEmpty(Node **head) ...
only inspects the list. It doesn't modify it, so it is enough to pass a node pointer:
int isEmpty(Node *head) ...
This function doesn't modify the contents of the nodes, either, so this could be made explicit:
int isEmpty(const Node *head) ...
On the other hand, the push, pop and updateprt functions must be able to change the head via a pointer, so they require a pointer to a node pointer. Your pop function, which always changes the head, does this. The other functions look like this:
void push(Node** head, int d, int p)
{
Node* start = (*head);
// ... do stuff with start, leave head alone ...
}
Here, you have just used the pointer to node pointer as an overly obscure way to pass in information about the head, but you never modify it (except in the special case of inserting into an ampty list).
Here's how that push function should look like:
void push(Node **head, int d, int p)
{
Node *temp = newNode(d, p);
while (*head && (*head)->priority < p) {
head = &(*head)->next;
}
temp->next = *head;
*head = temp;
}
Note how there aren't any special cases. When you call push(&queue, ...), you pass the address of the head pointer and you can modify the local variable queue in the calling function by assigning to *head. When you walk through the list with head = &(*head)->next, head holds the address of the next field of the previous node, which you can also modify via *head. The pointer to a pointer adds one level of indirection and tells you where you have come from and lets you modify that value.
In the same vein, you can change (and simplify) your updateptr function:
void updateprt(Node** head, int data)
{
while (*head && (*head)->data != data) {
head = &(*head)->next;
}
if (*head) pop(head);
}
With these changes, your program should work, but there are other things to note:
if (weight[src][dest] != 0 || weight[dest][src] != 0 && w < weight[src][dest]) ...
The condition (w1 == 0 || w2 == 0 && w < w1) is parsed as (w1 == 0 || (w2 == 0 && w < w1)), which probably isn't what you want. The check for zero is ot done correctly, because you never initialize weight. (You could use calloc instead of malloc to create a zero-initialized array.)`
But why have a separate array of weights at all? You could store the weight with each edge:
struct adjlistnode {
int data; // destination vertex
int weight;
struct adjlistnode* next;
};
The same goes for the arrays:
int Distance[100000], path[50];
Both arrays provide one entry for each vertex. The first one is too generous ("I'll allocate a bit more, just in case ..."), the second could be too small. (You don't need the path for the task, but it's always nice to be able to verify it. The variable isn't a path, however, it holds the next step towards the starting point for each vertex.)
The competition rules say that there are at most 3,000 nodes, so you could just dimension your arrays with [3000], but you cold also make them part of the graph structure and allocate according to the number of vertices.
Good luck!

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