Write Merge sort routine for sorting linked list
/*
* Merge Sort
*/
void MergeSort(nodeptr* headRef) {
nodeptr head = *headRef;
nodeptr a;
nodeptr b;
if ((head == NULL) || (head->next == NULL)) {
return;
}
FrontBackSplit(head, &a, &b); // Split list into 'a' and 'b' sublists
MergeSort(&a); // Recursively sort the sublists 'a' and 'b'
MergeSort(&b);
*headRef = SortedMerge(a, b); //merge the two sorted lists together
}
/*
* Takes two lists sorted in increasing order, and splices their
* nodes together to make one big sorted list which is returned.
*/
nodeptr SortedMerge(nodeptr a, nodeptr b)
{
nodeptr result = NULL;
nodeptr* lastPtrRef = &result;
while (1) {
if (a == NULL) {
*lastPtrRef = b;
break;
}
else if (b == NULL) {
*lastPtrRef = a;
break;
}
if (a->data <= b->data) {
MoveNode(lastPtrRef, &a);
} else {
MoveNode(lastPtrRef, &b);
}
lastPtrRef = &((*lastPtrRef)->next);
}
return(result);
}
/*
* Split the nodes of the given list into front and back halves,
* and return the two lists using the reference parameters.
* If the length is odd, the extra node should go in the front list.
*/
void FrontBackSplit(nodeptr source, nodeptr* frontRef, nodeptr* backRef)
{
nodeptr singlestep = NULL;
nodeptr doublestep = NULL;
if(source == NULL) {
*frontRef = NULL;
*backRef = NULL;
} else {
*frontRef = source;
doublestep = source->next;
singlestep = source;
while(doublestep != NULL) {
if(doublestep->next != NULL)
doublestep = doublestep->next->next;
else
break;
singlestep = singlestep->next;
}
*backRef = singlestep->next;
singlestep->next = NULL;
}
}
/*
* Merge Sort
*/
void MergeSort(nodeptr* headRef) {
nodeptr head = *headRef;
nodeptr a;
nodeptr b;
if ((head == NULL) || (head->next == NULL)) {
return;
}
FrontBackSplit(head, &a, &b); // Split list into 'a' and 'b' sublists
MergeSort(&a); // Recursively sort the sublists 'a' and 'b'
MergeSort(&b);
*headRef = SortedMerge(a, b); //merge the two sorted lists together
}
/*
* Takes two lists sorted in increasing order, and splices their
* nodes together to make one big sorted list which is returned.
*/
nodeptr SortedMerge(nodeptr a, nodeptr b)
{
nodeptr result = NULL;
nodeptr* lastPtrRef = &result;
while (1) {
if (a == NULL) {
*lastPtrRef = b;
break;
}
else if (b == NULL) {
*lastPtrRef = a;
break;
}
if (a->data <= b->data) {
MoveNode(lastPtrRef, &a);
} else {
MoveNode(lastPtrRef, &b);
}
lastPtrRef = &((*lastPtrRef)->next);
}
return(result);
}
/*
* Split the nodes of the given list into front and back halves,
* and return the two lists using the reference parameters.
* If the length is odd, the extra node should go in the front list.
*/
void FrontBackSplit(nodeptr source, nodeptr* frontRef, nodeptr* backRef)
{
nodeptr singlestep = NULL;
nodeptr doublestep = NULL;
if(source == NULL) {
*frontRef = NULL;
*backRef = NULL;
} else {
*frontRef = source;
doublestep = source->next;
singlestep = source;
while(doublestep != NULL) {
if(doublestep->next != NULL)
doublestep = doublestep->next->next;
else
break;
singlestep = singlestep->next;
}
*backRef = singlestep->next;
singlestep->next = NULL;
}
}
No comments:
Post a Comment