diff --git a/merge_sort b/merge_sort new file mode 100644 index 0000000..6fe35af --- /dev/null +++ b/merge_sort @@ -0,0 +1,141 @@ +// C++ code for linked list merged sort +#include +using namespace std; + +/* Link list node */ +class Node { +public: + int data; + Node* next; +}; + +/* function prototypes */ +Node* SortedMerge(Node* a, Node* b); +void FrontBackSplit(Node* source, + Node** frontRef, Node** backRef); + +/* sorts the linked list by changing next pointers (not data) */ +void MergeSort(Node** headRef) +{ + Node* head = *headRef; + Node* a; + Node* b; + + /* Base case -- length 0 or 1 */ + if ((head == NULL) || (head->next == NULL)) { + return; + } + + /* Split head into 'a' and 'b' sublists */ + FrontBackSplit(head, &a, &b); + + /* Recursively sort the sublists */ + MergeSort(&a); + MergeSort(&b); + + /* answer = merge the two sorted lists together */ + *headRef = SortedMerge(a, b); +} + +/* See https:// www.geeksforgeeks.org/?p=3622 for details of this +function */ +Node* SortedMerge(Node* a, Node* b) +{ + Node* result = NULL; + + /* Base cases */ + if (a == NULL) + return (b); + else if (b == NULL) + return (a); + + /* Pick either a or b, and recur */ + if (a->data <= b->data) { + result = a; + result->next = SortedMerge(a->next, b); + } + else { + result = b; + result->next = SortedMerge(a, b->next); + } + return (result); +} + +/* UTILITY FUNCTIONS */ +/* 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. + Uses the fast/slow pointer strategy. */ +void FrontBackSplit(Node* source, + Node** frontRef, Node** backRef) +{ + Node* fast; + Node* slow; + slow = source; + fast = source->next; + + /* Advance 'fast' two nodes, and advance 'slow' one node */ + while (fast != NULL) { + fast = fast->next; + if (fast != NULL) { + slow = slow->next; + fast = fast->next; + } + } + + /* 'slow' is before the midpoint in the list, so split it in two + at that point. */ + *frontRef = source; + *backRef = slow->next; + slow->next = NULL; +} + +/* Function to print nodes in a given linked list */ +void printList(Node* node) +{ + while (node != NULL) { + cout << node->data << " "; + node = node->next; + } +} + +/* Function to insert a node at the beginging of the linked list */ +void push(Node** head_ref, int new_data) +{ + /* allocate node */ + Node* new_node = new Node(); + + /* put in the data */ + new_node->data = new_data; + + /* link the old list off the new node */ + new_node->next = (*head_ref); + + /* move the head to point to the new node */ + (*head_ref) = new_node; +} + +/* Drier program to test above functions*/ +int main() +{ + /* Start with the empty list */ + Node* res = NULL; + Node* a = NULL; + + /* Let us create a unsorted linked lists to test the functions +Created lists shall be a: 2->3->20->5->10->15 */ + push(&a, 15); + push(&a, 10); + push(&a, 5); + push(&a, 20); + push(&a, 3); + push(&a, 2); + + /* Sort the above created Linked List */ + MergeSort(&a); + + cout << "Sorted Linked List is: \n"; + printList(a); + + return 0; +}