I'm trying to implement Shell sort on a linked list. I divide my original linked list into sub linked list, which contain nodes that have 'k' gap regarding the shell sort algorithm. I want to sort the sub linked list by manipulating the 'next' pointers instead of changing its data field. So I have a sortList function that traverses the linked list and swaps the nodes with swapNodes if it encounters any unordered nodes.
When I pass an unordered linked list with two elements to the sortList I keep loosing one of the nodes in my list. For example, I have 50 and -84 in my list, I pass it to sortList. After the sortList figures that they're unordered it calls swapNodes, but once swapNodes terminates, the resulting list only has 50.
I tried to gdb and found out that when I'm in swapNodes scope the list gets sorted successfully without losing a node, but when it terminates and turns back to sortList scope, both the head and curr points only to 50 and their 'next' field is NULL.
My functions:
void sortList(Node * head, long * n_comp) {
Node * curr;
int didSwap = 1;
while(didSwap) {
didSwap = 0;
for(curr = head; curr -> next != NULL; ) {
*n_comp += 1; //number of comparison
if(curr->value > curr->next->value) {
swapNodes(curr, curr->next, &head);
didSwap = 1;
}
curr = curr -> next;
if (!curr) break;
}
}
}
void swapNodes(Node * p1, Node * p2, Node ** start)
{
Node *p1pre = NULL;
Node *p1curr = *start;
while (p1curr && p1curr!=p1)
{
p1pre = p1curr;
p1curr = p1curr->next;
}
Node *p2pre = NULL;
Node *p2curr = *start;
while (p2curr && 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;
return;
}
``