Hey guy's I have been trying to implement merge sort for linked list's. It works for reversed numbers, but when trying to sort random data it does not sort correctly. As well as when sorting two or more instances of the same number ie you would expect {1, 2, 3, 4 , 1, 2, 3, 4} to sort as {1, 1, 2, 2, 3, 3, 4, 4} but it returns as {1, 2, 3, 4 , 1, 2, 3, 4}. Is there something wrong with my implementation of the algorithm or is this actually how merge sort works?
Please note my code is broken up into a bunch of helper functions if you think the problem lies in a function that I didn't include I will gladly include it.
Merge Sort:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
node* mergesort(node* left, ofstream& outf)
{
outf << "Merge sort ";//all outf entries are for debugging purposes
node* right;
outf << length(left) << " entries" << endl;
if(left -> link != nullptr)// if list isn't shorter then 1 entry then sort it...
{
right = split(left); //create the right sublist
//Call merge sort recursively for both the left and the right sublists
outf << "Left : ";
showlist(left, outf);
outf << "Right : ";
showlist(right, outf);
return merge(mergesort(left, outf), mergesort(right, outf)); //Merge the two sorted lists and return them as one sorted list
}
outf << "returning " << left -> value << endl;
return left; //otherwise list is 1 long or shorter so return it
}
| |
Merge:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
node* merge(node* list1, node* list2)
{
node* tmp = nullptr; //create a node to find the end of a list without losing its head
while(list1 != nullptr || list2 != nullptr)
{
if(list1 != nullptr && list2 != nullptr)//if both lists have at least 1 node... continue with merge
{
if(list1 -> value <= list2 -> value)
{
tmp = list1;
while (tmp -> link != nullptr) tmp = tmp -> link; //Advance to the end of the list
tmp -> link = list2; //Set the end of list 1 to link to list 2
return list1; //return the merged list
}
else
{
tmp = list2;
while (tmp -> link != nullptr) tmp = tmp -> link; //Advance to the end of the list
tmp -> link = list1; //Set the end of list 2 to link to list 1
return list2; //return the merged list
}
}
else if(list1 = nullptr)return list2; //if list 1 is empty merging is unneccesary so return list 2
else return list1;//otherwise the only remaining possibility is list 2 is empty so return list 1
}
}
| |
Split:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
node* split(node* list)
{
node* pivot;
node* right;
int i;
if(list -> link != nullptr) //If list is longer then one node continue...
{
pivot = list;
for(i=1; i<(length(list))/2; i++) pivot = pivot -> link; //navigate to the center of the list
right = pivot -> link; //Create the right sublist
pivot -> link = nullptr; //Split it from the left sublist
return right; //return head of right
}
else return nullptr;
}
| |
Length:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
int length(node* list)
{
int i = 0;
if(!empty(list))
{
while(list != nullptr)
{
i++;
list = list -> link;
}
return i;
}
else return 0; //If list is empty length is 0
}
| |