I have got a problem with bubble sorting with a linked list. I have not found the bug in my simple code for few hours. Could you look at that?
int listSort(node_t ** _list)
{
int size = listSize(_list);
for(int i = 0; i < size; i++)
{
node_t *pointer = *_list;
for(int j = 0 ; j < size - 1; j++)
{
if(strcmp(pointer->title, pointer->next->title) > 0)
listSwapWithNext(_list, j);
pointer = pointer->next;
}
}
return 0;
}
and here's swap function (but it seems to work fine, because I tested manually all boundary cases):
int listSwapWithNext(node_t **_list, size_t first)
{
node_t *pointer = *_list;
node_t *ptr_b;
node_t *ptr_c;
node_t *ptr_d;
if(!first)
ptr_b = pointer;
for(size_t i = 0; pointer->next->next; i++, pointer = pointer->next)
{
if(i == first - 1 || first == 0)
{
if(first)
ptr_b = pointer->next;
ptr_c = ptr_b->next;
ptr_d = ptr_c->next;
if(first)
pointer->next = ptr_c;
else
*_list = ptr_c;
ptr_c->next = ptr_b;
ptr_b->next = ptr_d;
break;
}
}
return 0;
}
It causes this crash (on line 229):
When I modified the condidition of inner loop in sort function to:
for(int j = 0; j < size - 1 && pointer->next; j++)
to prevent reading from bad address, I noticed strange thing. Inner loop somtimes run exactly one time less than it should.
Thank you!
EDIT: Here's modified version of sort function with prevent condition in inner loop and my debug indicators (made with printf()):
int listSort(node_t ** _list)
{
int size = listSize(_list);
int i;
for(i = 0; i < size; i++)
{
node_t *pointer = *_list;
int j;
for(j = 0 ; j < size - 1 && pointer->next; j++)
{
if(strcmp(pointer->title, pointer->next->title) > 0)
listSwapWithNext(_list, j);
printf("# %d %d\n", i, j);
pointer = pointer->next;
}
printf("\n");
}
return 0;
}
Here's the result in console. Look, it doesn't do every cycle so it gaves bad sorting.
EDIT2: Here's the essention of the problem. http://pastebin.com/e5K6C1A2
Still cant resolve this issue.
pointer = pointer->next
is not correct in the case where a swap is made. If you made a swap,pointer
should remainpointer
because it has been moved forward by one element already.Edit: I mean do this: