C segmentation fault when trying to implement LinkedList - c

I've got the following code:
#include <stdio.h>
#include <stdlib.h>
#define MAXN 100
typedef int key;
typedef int data;
struct list * createElement(key k, data info);
struct list{
key k;
data info;
struct list *next;
};
struct list *L;
void init(key k, data info)
{
L = createElement(k, info);
}
struct list * createElement(key k, data info)
{
struct list *temp;
temp = (struct list *) malloc(sizeof(*temp));
temp->k = k;
temp->info = info;
return temp;
}
void insert(struct list * element)
{
element->next = L;
L = element;
}
void insertBefore(struct list * element, key k)
{
struct list * currentElement = L;
while(currentElement != NULL)
{
if(currentElement->k == k)
{
struct list *temp = currentElement;
currentElement = element;
currentElement->next = temp;
return;
}
currentElement = currentElement->next;
}
}
void insertAfter(struct list * element, key k)
{
struct list * currentElement = L;
while(currentElement != NULL)
{
if(currentElement->k == k)
{
struct list *temp = currentElement->next;
currentElement->next = element;
element->next = temp;
return;
}
currentElement = currentElement->next;
}
}
void deleteElement(struct list * element)
{
struct list * currentElement = L;
while(currentElement != NULL)
{
if(currentElement == element)
{
struct list * temp = currentElement;
currentElement = currentElement->next;
free(temp);
return;
}
currentElement = currentElement->next;
}
}
struct list * getElementByKey(key k) {
printf("\n1");
struct list *currentElement = L;
printf("2");
while(currentElement != NULL)
{
printf("3");
if(currentElement->k == k)
{
printf("4");
return currentElement;
}
printf("5");
currentElement = currentElement->next;
printf("6");
}
printf("There is no such element in the list");
}
struct list * pop()
{
struct list *element = L;
L = L->next;
return element;
}
int main()
{
init(0, 13);
struct list * element = createElement(5, 155);
insert(element);
struct list * k = createElement(7, 243);
insert(k);
//insertBefore(createElement(3, 100), 5);
printf("The first element value is: %d", pop()->info);
printf("The second element value is: %d", pop()->info);
printf("The element value is: %d", getElementByKey(5)->info);
return 0;
}
So when i execute it the debugger gives me segmantation fault on line 84 which is if(currentElement->k == k) on method getElementByKey. I know that i'm trying to access an unexisting element(because i use the pop method and it removes the first element in the list) but it should print me a warning message. it seems that there is a problem in the previous element's key or something that i failed to notice.

In your createElement function, you forgot to initialize the next pointer to NULL.
struct list * createElement(key k, data info)
{
struct list *temp;
temp = (struct list *) malloc(sizeof(*temp));
temp->k = k;
temp->info = info;
temp->next = NULL;
return temp;
}
So when you're browsing your list, it never finds the last element of the list because next pointer never equals NULL, and goes at some random position in the memory, trying to access to parts it is not allowed to do so.

When deleting an element (using deleteElement()) you miss to re-initialise L.
The segmenataion violation in if(currentElement->k == k)most likey dues to currentElement referring to an invalid memory address. As you test if against NULL some lines before line 84, it can only be the case that currentElement had either been assigned an invalid address explicitly or the address it points had been freed already.
From the code shown in deleteElement() I assume the latter.

two problem
1)at createElement()
need
temp->next = NULL;
2)at insertBefore()
not change pointer of list
currentElement = element;
e.g)
void insertBefore(struct list * element, key k)
{
struct list * currentElement = L; //add case of L->k
while(currentElement != NULL)
{
if(currentElement->next && currentElement->next->k == k)
{
element->next = currentElement->next;
currentElement->next = element;
return;
}
currentElement = currentElement->next;
}
}

Related

Why is the list NULL?

Why is the list NULL?
typedef struct Node
{
int elem;
struct Node* next;
} Node;
typedef struct Node* List;
List empty()
{
List l = malloc(sizeof(Node));
return l;
}
void addl(List l, int e)
{
Node *n = malloc(sizeof(Node));
n->elem = e;
n->next = l;
l = n;
}
int main()
{
List l = empty();
addl(l, 1);
addl(l, 2);
if (l == NULL)
{
printf("IS NULL");
}
return 0;
}
return → IS NULL
why ? Why not addr to the list?
I have made improvemnts and fixed some parts of your code. Compare it with yours and find your mistakes.
#include<stdio.h>
#include <stdlib.h>
struct Node
{
int elem;
struct Node *next;
};
typedef struct Node Node;
typedef struct Node *List;
List newList(int e)
{
List l = malloc(sizeof(Node));
if (l == NULL)
{
printf("IS NULL");
return NULL;
}
l->elem = e;
l->next = NULL;
return l;
}
void addl(List l, int e)
{
List n = malloc(sizeof(Node));
if(n == NULL) {
printf("Memory allocation error");
}
printf("New node: %p\n", n);
n->next = NULL;
n->elem = e;
List iter = l;
if(iter->next == NULL) {
// If there is only one node (head) in the node add the new one to the next
iter->next = n;
}
else {
while(iter->next) {
// Iterate until find the last node
iter = iter->next;
}
iter->next = n; // Finally add the new node to the end of the list
}
}
int main()
{
List l = newList(0);
addl(l, 1);
addl(l, 2);
List iterate = l;
int i = 1;
do {
printf("%d. node's element is %d\n", i, iterate->elem);
iterate = iterate->next;
i++;
if(iterate->next == NULL) {
// Catch the last node
printf("%d. node's element is %d\n", i, iterate->elem);
}
}
while(iterate->next);
return 0;
}
The output of the code:
New node: 0x8292c0
New node: 0x8296f0
1. node's element is 0
2. node's element is 1
3. node's element is 2

Trying to swap 2 adjacent nodes in a linked list in plain C without double pointers

[ WOW - Someone gave me and negative point for my question ]
[ You could at least put a comment why you did not like my question ]
I am stuck.
I remember doing something similar in C++ but for some reason, I can't get it to work in plain C.
I'm trying to swap 2 nodes in a singly linked list.
The starting list is populated as [9,8,7,5,3,2] and I'm trying to bubble sort it, 2 nodes at a time to final list of [2,3,5,7,8,9]
The first iteration(swap) works find with the head. The list returns perfect with [8,9,7,5,3,2]
...but in the second iteration, I loose the 7 and get [8,9,5,3,2] which is WTF and I tried changing the code a bit but I have lost hope.
Can someone actually find what I did wrong. Please no double pointers... if it's only possible with double pointers... Why and How? since I have no idea what are double pointers?
Here is my program so far:
/*
___ENTER TITLE HERE___
Author : Patrick Miron
Date : Oct 20, 2021
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct listNode
{
int data;
struct listNode *next;
} listNode;
typedef struct list
{
struct listNode *head;
struct listNode *tail;
} list;
int isEmpty( const list *l)
{
return (l == NULL);
}
void printList(list *ptrToList, char *title)
{
int counter = 0; //Counter to count the listItem printed so we can add a carriage return at each 5th element.
printf("%s\n", title);
listNode *ptrToCurrentItem = ptrToList->head;
while (ptrToCurrentItem != NULL)
{
counter++;
printf("%d", ptrToCurrentItem->data);
if (counter % 5 != 0)
{
printf(" : ");
}
else
{
printf("\n");
}
ptrToCurrentItem = ptrToCurrentItem->next;
}
}
list *createListWithHeadData(int data)
{
list *ptrList = malloc((sizeof(ptrList)));
listNode *ptrNewNode = malloc(sizeof(listNode));
ptrNewNode->data = data;
ptrList->head = ptrNewNode;
ptrList->tail = ptrNewNode;
return ptrList;
}
void addToFrontList(list *ptrList, listNode *ptrListNode)
{
listNode *tempPtr = ptrList->head;
ptrList->head = ptrListNode;
ptrListNode->next = tempPtr;
}
list *arrayToList(int data[], int size)
{
list *ptrToNewList = createListWithHeadData(data[0]);
for (int i = 1; i < size; i++)
{
listNode *ptrToNewListNode = malloc(sizeof(listNode));
ptrToNewListNode->data = data[i];
addToFrontList(ptrToNewList, ptrToNewListNode);
}
return ptrToNewList;
}
int count(listNode *ptrToHead)
{
if (ptrToHead == NULL)
{
return 0;
}
else
{
return (1 + count(ptrToHead->next));
}
}
void concat(listNode *head1, listNode *head2)
{
assert(head1 != NULL);
if (head1->next == NULL)
{
head1->next = head2;
}
else
{
concat(head1->next, head2);
}
}
void insert(
listNode *p1, // first element
listNode *p2, // second element
listNode *q) // new element to insert between first and second element
{
assert(p1->next == p2);
p1->next = q;
q->next = p2;
}
void delete(listNode *listNode)
{
assert(listNode != NULL);
listNode = NULL;
}
void deleteList(list *list)
{
if (list->head != NULL)
{
list->head = list->head->next;
deleteList(list);
}
}
void swapListNodeWithNext(listNode *ptrToListNode1)
{
//Swap items
listNode *ptrTempNode1 = ptrToListNode1->next;
listNode *ptrTempNode2 = ptrToListNode1->next->next;
//Set the next node from temp1 (ptrToListNode->next->next) to itself
//Could be written as ptrToListNode->next->next = ptrToListNode
ptrTempNode1->next = ptrToListNode1;
ptrToListNode1->next = ptrTempNode2;
ptrToListNode1 = ptrTempNode1;
ptrTempNode1 = NULL;
ptrTempNode2 = NULL;
}
void sortList(list *ptrToListToSort)
{
if (ptrToListToSort->head == NULL)
{
return;
}
listNode *ptrToCurrentItem = ptrToListToSort->head;
listNode *ptrToLastUnsortedItem = ptrToListToSort->tail;
while (ptrToLastUnsortedItem != ptrToListToSort->head)
{
ptrToCurrentItem = ptrToListToSort->head;
while(ptrToCurrentItem->next != NULL)
{
if (ptrToCurrentItem->data > ptrToCurrentItem->next->data)
{
listNode *ptrToHead = ptrToListToSort->head;
if (ptrToCurrentItem == ptrToListToSort->head)
{
ptrToHead = ptrToCurrentItem->next;
}
//Swap items
swapListNodeWithNext(ptrToCurrentItem);
ptrToListToSort->head = ptrToHead;
}
else
{
ptrToCurrentItem = ptrToCurrentItem->next;
}
}
ptrToLastUnsortedItem = ptrToCurrentItem;
}
}
int main(void)
{
printf("\n");
list listOfInt;
int data[6] = { 2, 3, 5, 7, 8, 9 };
list *ptrToNewList = arrayToList(data, 6);
printList(ptrToNewList, "Array to Element List");
sortList(ptrToNewList);
printList(ptrToNewList, "Sorted List");
printf("\n");
printf("...End of line...\n");
printf("\n");
return 0;
}
I found a couple issues but the major one was that I did not change my previous ptr's next ( ptrPreviousItem->next) to point to the correct item after the swap. I was only changing the pointer to current item which was just a copy of the head advancing thru my iterations and the previous->next was still pointing to the original item.
Why in the world did it work for my first iteration? Probably because I would not update the last item since it was in correct order it would not get updated after that.
I have included a correct version of my singly linked list bubble sort with pointers. It works and I hope it can help the next person. Believe me alot of the tutorial on the subject barely make the code more readable then identifiers like "a" and "b"...
Oh, and #chqrlie, I don't understand some of the corrections you made in my previous question, some of them are quite unnecessary the others were formated like that when I put the code in brackets and the * in pointers can be put where you want. int* likeThis; int * likeThis; or int *likeThis. But I do usually format it like you with the asterix right against the identifier. I use a space between them when I mean the dereferenced value. Cheers!
/*
Singly Linked List Bubble Sort with Pointers
Author : Patrick Miron
Date : Nov 17, 2021
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct listNode
{
int data;
struct listNode * next;
} listNode;
typedef struct list
{
struct listNode *head;
struct listNode *tail;
} list;
int isEmpty( const list *l)
{
return (l == NULL);
}
void printList(list *ptrToList, char *title)
{
int counter = 0; //Counter to count the listItem printed so we can add a carriage return at each 5th element.
printf("%s\n", title);
listNode *ptrToCurrentItem = ptrToList->head;
while (ptrToCurrentItem != NULL)
{
counter++;
printf("%d", ptrToCurrentItem->data);
if ((counter % 5) != 0 && (ptrToCurrentItem->next != NULL))
{
printf(" : ");
}
else
{
printf("\n");
}
ptrToCurrentItem = ptrToCurrentItem -> next;
}
}
list *createListWithHeadData(int data)
{
list *ptrList = malloc((sizeof(list)));
listNode *ptrNewNode = malloc(sizeof(listNode));
ptrNewNode->data = data;
ptrNewNode->next = NULL;
ptrList->head = ptrNewNode;
ptrList->tail = ptrNewNode;
return ptrList;
}
void addToFrontList(list *ptrList, listNode *ptrListNode)
{
listNode *tempPtr = ptrList->head;
ptrList->head = ptrListNode;
ptrListNode->next = tempPtr;
}
list *arrayToList(int data[], int size)
{
list *ptrToNewList = createListWithHeadData(data[0]);
for (int i =1; i<size; i++)
{
listNode *ptrToNewListNode = malloc(sizeof(listNode));
ptrToNewListNode->data = data[i];
addToFrontList(ptrToNewList, ptrToNewListNode);
}
return ptrToNewList;
}
int count(listNode *ptrToHead)
{
if (ptrToHead == NULL)
{
return 0;
}
else
{
return (1 + count(ptrToHead->next));
}
}
void concat(listNode *head1, listNode *head2)
{
assert(head1 != NULL);
if (head1->next == NULL)
{
head1->next = head2;
}
else
{
concat(head1->next, head2);
}
}
void insert(
listNode *p1, // first element
listNode *p2, // second element
listNode *q) // new element to insert between first and second element
{
assert(p1->next == p2);
p1->next = q;
q->next = p2;
}
void delete(listNode *listNode)
{
assert(listNode != NULL);
listNode = NULL;
}
void deleteList(list *list)
{
if (list->head != NULL)
{
list->head = list->head->next;
deleteList(list);
}
}
void swapListNodeWithNext(listNode *ptrToCurrentNode, listNode *ptrToPreviousNode)
{
//Swap items
listNode *ptrTempNode1 = ptrToCurrentNode->next;
listNode *ptrTempNode2 = ptrToCurrentNode->next->next;
//Set the next node from temp1 (ptrToListNode->next->next) to itself
//Could be written as ptrToListNode->next->next = ptrToListNode
ptrTempNode1->next = ptrToCurrentNode;
ptrToCurrentNode->next = ptrTempNode2;
ptrToCurrentNode = ptrTempNode1;
if (ptrToPreviousNode != NULL)
{
ptrToPreviousNode->next = ptrToCurrentNode;
}
ptrTempNode1 = NULL;
ptrTempNode2 = NULL;
}
void sortList(list *ptrToListToSort)
{
if (ptrToListToSort->head == NULL)
{
return;
}
listNode *ptrToCurrentItem = ptrToListToSort->head;
listNode *ptrToPreviousItem = NULL;
int sizeOfList = count(ptrToListToSort->head);
int innerLoopCounter = 0;
int unsortedElementLeft = sizeOfList;
listNode *ptrToHead = ptrToListToSort->head;
int swappedAtLeastOneItem = 0;
for (int indexOuterLoop = 0; indexOuterLoop < sizeOfList; indexOuterLoop++)
{
ptrToCurrentItem = ptrToListToSort->head;
while((ptrToCurrentItem->next != NULL) && (innerLoopCounter < unsortedElementLeft))
{
// If the data in the next item greater then the current item, swap nodes.
if (ptrToCurrentItem->data > ptrToCurrentItem->next->data)
{
swappedAtLeastOneItem = 1;
// If the current item is the head of the list, and since it will be swap, point to the next item.
if (ptrToCurrentItem == ptrToListToSort->head)
{
ptrToHead = ptrToCurrentItem->next;
}
//Swap items
swapListNodeWithNext(ptrToCurrentItem, ptrToPreviousItem);
//if the ptrToHead has changed, then update the changes.
if (ptrToListToSort->head != ptrToHead)
{
ptrToListToSort->head = ptrToHead;
}
}
// if the nodes do not need to swap, make sure to update the current item and previous items.
else
{
if (ptrToCurrentItem->next != NULL)
{
ptrToCurrentItem = ptrToCurrentItem->next;
}
}
if (ptrToPreviousItem != NULL)
{
ptrToPreviousItem = ptrToPreviousItem->next;
}
else
{
ptrToPreviousItem = ptrToHead;
}
innerLoopCounter++;
}
// If during the first loop no items were swap then exit early all items are already in order.
if (!swappedAtLeastOneItem)
{
printf("**List is already sorted!**\n");
return;
}
unsortedElementLeft--;
innerLoopCounter=0;
ptrToPreviousItem = NULL;
if (ptrToCurrentItem->next == NULL)
{
ptrToListToSort->tail = ptrToCurrentItem;
}
}
}
int main(void)
{
printf("\n");
int data1[6] = {2,3,5,7,8,9};
list *ptrToNewList = arrayToList(data1,6);
printList(ptrToNewList, "Array to Element List");
sortList(ptrToNewList);
printList(ptrToNewList, "Sorted List");
printf("\n");
printf("----------------------------\n");
printf("\n");
int data2[8] = {10,11,2,3,5,7,8,9};
ptrToNewList = arrayToList(data2,8);
printList(ptrToNewList, "Array to Element List");
sortList(ptrToNewList);
printList(ptrToNewList, "Sorted List");
printf("\n");
printf("\n");
printf("----------------------------\n");
printf("\n");
int data3[10] = {10,11,2,3,5,7,8,1,9,1};
ptrToNewList = arrayToList(data3,10);
printList(ptrToNewList, "Array to Element List");
sortList(ptrToNewList);
printList(ptrToNewList, "Sorted List");
printf("\n");
printf("\n");
printf("----------------------------\n");
printf("\n");
int data4[10] = {1,1,1,1,1,1,1,1,1,1};
ptrToNewList = arrayToList(data4,10);
printList(ptrToNewList, "Array to Element List");
sortList(ptrToNewList);
printList(ptrToNewList, "Sorted List");
printf("\n");
printf("\n");
printf("----------------------------\n");
printf("\n");
int data5[10] = {21,19,16,13,10,9,6,2,1,1};
ptrToNewList = arrayToList(data5,10);
printList(ptrToNewList, "Array to Element List");
sortList(ptrToNewList);
printList(ptrToNewList, "Sorted List");
printf("\n");
printf("\n");
printf("----------------------------\n");
printf("\n");
printf("...End of line...\n");
printf("\n");
return 0;
}
Please note, I did not finish my commenting so don't judge me, I always complete it last.
Hope this helps for anyone having similar issues to me.

Linked lists and arrays

I have to make linked lists that contain all the non zero values from an array and print it out. However, my code is printing out the same value for how many non zero elements there are in the array.
The creation of the linked list and printing of the linked list are two separate functions.
The addLink function creates the linked list
void addlink(DataPtr *start, int element, double value) {
Data last = *start;
Data newPtr;
newPtr = malloc(sizeof(Data));
newPtr->element = element;
newPtr->usage = value;
newPtr->next = NULL;
if(*start == NULL) {
*start = newPtr;
return;
newPtr->element = element;
newPtr->usage = value;
newPtr->next = NULL;
}
while(last->next != NULL) {
last = last->nextPtr;
last->next = newPtr;
return;
}
}
The print function prints the linked list
void print(Data *start) {
Data current = *start;
while(current != NULL) {
printf("%d ", current->element);
printf("%.3lf", current->value);
current = current->next;
}
printf("\n");
}
This is how i call it in my main
for(k = 0; k < 50; k++) {
if(values[k] != 0) {
value = values[k];
addlink(&start,k,value);
print(&start);
}
}
struct data{
int element;
double value;
struct data *next;
};
typedef struct data Data;
typedef Data *DataPtr;
DataPtr start = NULL;
Here is correct implementation of your list:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
typedef struct data {
int element;
double value;
struct data *next;
} data_t;
void print(data_t *start);
void addlink(data_t **start, int element, double value);
int main()
{
int values[50] = { 0 };
int value = 0;
int k;
data_t *start = NULL;
//Give values some value
values[0] = 100;
values[1] = 250;
for(k = 0; k < 50; k++)
{
if(values[k] != 0)
{
value = values[k];
addlink(&start,k,value);
print(start);
}
}
}
void addlink(data_t **start, int element, double value)
{
data_t *newPtr;
newPtr = malloc(sizeof(data_t));
newPtr->element = element;
newPtr->value = value;
*start = newPtr;
}
void print(data_t *start)
{
data_t *current = start;
while(current != NULL)
{
printf("%d ", current->element);
printf("%f", current->value);
current = current->next;
}
printf("\n");
}
Your DataPtr idea, is no good. The "data_t" implementation is generally what you will see when seeing linked lists. It is easiest implemented this way.
If you are trying to implement a list that adds the newest data_t to the end of the list...
Check out http://www.learn-c.org/en/Linked_lists for further explanation.
A correct function implementation can look the following way
int addlink( DataPtr *start, int element, double value )
{
DataPtr newPtr = malloc(sizeof(Data));
int success = newPtr != NULL;
if ( success )
{
newPtr->element = element;
newPtr->value = value;
newPtr->next = NULL;
while ( *start != NULL ) start = &( *start )->next;
*start = newPtr;
}
return success;
}
If you want to add new elements at the beginning of the list then the function can look like
int addlink( DataPtr *start, int element, double value )
{
DataPtr newPtr = malloc(sizeof(Data));
int success = newPtr != NULL;
if ( success )
{
newPtr->element = element;
newPtr->value = value;
newPtr->next = *start;
*start = newPtr;
}
return success;
}
As for showed by you the function implementation then it shall not even compile. For example in this code snippet
Data last = *start;
Data newPtr;
newPtr = malloc(sizeof(Data));
the expression *start has the type DataPtr while the initialized variable last has the type Data. The same problem exists for the variable newPtr.
The function print can look like
void print( DataPtr *start )
{
for ( DataPtr current = *start; current != NULL; current = current->next )
{
printf("%d ", current->element);
printf("%.3lf", current->value);
}
printf("\n");
}
And it is called like
print( &start );

sorting linked list simplest way

I am trying to code very basic sorting method for linked lists. I am getting unhandled exception. What is the mistake i am making? Here is my code:-
struct LinkedNode// structure for linked list
{
int data;
struct LinkedNode *next;
}*start = NULL;
following function creates a linked list
void CreateLinkedList()
{
LinkedNode *newNode, *current;
printf("enter 5 numbers to create linked list\n");
for(int i=0; i<5; i++)
{
newNode = (struct LinkedNode *)malloc(sizeof(LinkedNode));
scanf("%d", &newNode->data);
newNode->next = NULL;
if(start == NULL)
{
start = newNode;
current = newNode;
}
else
{
current->next = newNode;
current = newNode;
}
}
}
following function is used for sorting the linked list nodes
void SortLinkedList()
{
struct LinkedNode *node=NULL, *temp = NULL;
int tempvar;//temp variable to store node data
node = start;
temp = node->next;//temp node to hold node data and next link
while(node != NULL && node->next != NULL)
{
for(int j=0; j<5; j++)//value 5 because I am taking only 5 nodes
{
if(node->data > temp->data)//swap node data
{
tempvar = node->data;
node->data = temp->data;
temp->data = tempvar;
}
temp = temp->next;
}
node = node->next;
}
}
Try This code
void SortLinkedList()
{
struct LinkedNode *node=NULL, *temp = NULL;
int tempvar;//temp variable to store node data
node = start;
//temp = node;//temp node to hold node data and next link
while(node != NULL)
{
temp=node;
while (temp->next !=NULL)//travel till the second last element
{
if(temp->data > temp->next->data)// compare the data of the nodes
{
tempvar = temp->data;
temp->data = temp->next->data;// swap the data
temp->next->data = tempvar;
}
temp = temp->next; // move to the next element
}
node = node->next; // move to the next node
}
}
1 - outer while loop is use for the total number of pass that will require to sort the linked list..
2- In second while loop we are actually comparing the data of the nodes that we want to sort
Instead of implementing your own sort, you can just use qsort. Of course, qsort requires an array, but that is easy enough to create.
In this case, you know that the list has 5 members. But, if you didn't know, you could just count them.
int size_of_list = 0;
struct LinkedNode *p;
for (p = start; p != NULL; p = p->next) ++size_of_list;
if (size_of_list == 0) {
// Nothing to do
return;
}
Now you can create your array;
struct LinkedNode *arr[size_of_list + 1], **arrp = arr;
for (p = start; p != NULL; p = p->next) *arrp++ = p;
*arrp = NULL;
Then, use qsort on arr. There are lots of examples, but the trick is writing an appropriate comparison function.
int cmp_LinkedNode(const void *a, const void *b) {
const struct LinkedNode * const *aa = a;
const struct LinkedNode * const *bb = b;
return ((*aa)->data > (*bb)->data) - ((*aa)->data < (*bb)->data);
}
//...
qsort(arr, size_of_list, sizeof(*arr), cmp_LinkedNode);
And then, rewire the list into the sorted order.
for (int i = 0; i < size_of_list; ++i) arr[i]->next = arr[i+1];
start = arr[0];
yeah sorting a linked list using nodes/links is a pretty hard job. Spend hours doing it myself but since i have done it why not help others..
What you need to do is simply find the minimum value in your list. Swap it with the head node and the recur for head->next.
The code for sort is only of 3 to 4 lines if you have FindMin() and Swap() functions made..
here is the complete code for sort(),swap()and findmin().
void sort(node **start)
{
if (((*start)->next == NULL) || (*start == NULL))
{
return;
}
node *min = findmin(*start);
swap(*start, min, start);
sort(&((*start)->next));
}
void swap(node *p1, node *p2, node **start)
{
node *p1pre = NULL;
node *p1curr = *start;
while (p1curr!=p1)
{
p1pre = p1curr;
p1curr = p1curr->next;
}
node *p2pre = NULL;
node *p2curr = *start;
while (p2curr != p2)
{
p2pre = p2curr;
p2curr = p2curr->next;
}
if (p1pre != NULL)
{
p1pre->next = p2curr;
}
else
{
*start = p2curr;
}
if (p2pre != NULL)
{
p2pre->next = p1curr;
}
else
{
*start = p1curr;
}
node *temp = p2curr->next;
p2curr->next = p1curr->next;
p1curr->next = temp;
}
node* findmin(node *start)
{
int flag = 0;
if (start == NULL)
{
cout << "list is empty" << endl;
}
else
{
node *curr = start->next;
node *min = start;
while (curr->next != NULL)
{
if (min->value > curr->value)
{
min = curr;
flag++;
}
curr = curr->next;
}
if ((curr->next == NULL) && (min->value > curr->value))
{
min = curr;
flag++;
}
if (flag > 0)
{
return min;
}
}
}

Troubles with linked list - why aren't new elements being added to my list?

My linked list print function keeps printing only one value and I can't figure out why. Everything works as expected.
Here is the struct that I store in linked list:
typedef struct list_element {
int value;
struct list_element *next;
} list_element;
These are the functions to operate on list:
list_element createNewLinkedList()
{
list_element *myElement = (list_element *) malloc(sizeof(list_element));
myElement->value = 0;
myElement->next = NULL;
return *myElement;
}
int insertNewElementAtEndWithValue(list_element element, int value)
{
list_element *myElement = &element;
do {
if (myElement->next == NULL) {
list_element *new = (list_element *)malloc(sizeof(list_element));
new->value = value;
new->next = NULL;
myElement->next = new;
} else {
myElement = myElement->next;
}
} while (myElement->next != NULL);
}
int printListValues(list_element firstNode)
{
list_element *temp = &firstNode;
int sentinel = 1;
while (sentinel) {
printf(" %d,", temp->value);
if (temp->next != NULL) {
temp = temp->next;
} else {
sentinel = 0;
}
}
return 0;
}
And here is the function that prints only first value, 100:
void checkLinkedList()
{
list_element list = createNewLinkedList();
list.value = 100;
for (int i = 1; i < 10; i++) {
int value = rand();
insertNewElementAtEndWithValue(list, value);
}
printListValues(list);
}
What's wrong with that?
Your function
int insertNewElementAtEndWithValue(list_element element, int value)
is accepting a list_element object, meaning, a copy of the head of your list, what you want to pass is a pointer, so:
int insertNewElementAtEndWithValue(list_element *element, int value)
and this way you add the value to the actual list and not a copy of it.
You need to learn to use pointers, and use a debugger to check where your data stays.

Resources