/**
* Merge Sort a Linked List
* Anwar Mamat
* anwarmamat@gmail.com
*
*/
#include <iostream>
using namespace std;
/*
* Single Linked List Node
*/
template <typename T>
class Node
{
public:
T data;
Node* next;
Node(const T& d):data(d),next(NULL){};
~Node(){};
};
/*
* Push an item into the linked list. The item is added to the head;
*/
template<typename T>
void pushToLinkedList(Node<T>** head, const T& item)
{
Node<T>* t = new Node<T>(item);
if(*head == NULL){
*head = t;
}
else{
t->next = *head;
*head = t;
}
}
/*
* Print the linked list
*/
template<typename T>
void printLinkedList(Node<T> *head)
{
Node<T> *t = head;
while(t != NULL){
cout << t->data << ", ";
t = t->next;
}
cout << endl;
}
/*
* delete the linked list
*/
template<typename T>
void deleteLinkedList(Node<T> *head)
{
Node<T> *t = NULL;
while(head != NULL)
{
t = head->next;
delete head;
head = t;
}
}
/*
* Split the linked list in half.
* pre: Linked list head
* post: two linked lists. original head: left list.
* returns node pointer to the right list.
*/
template<typename T>
Node<T>* splitLinkedlist(Node<T> *head)
{
if(head == NULL || head->next == NULL)
return head;
Node<T> * fast = head->next;
Node<T> * slow = head;
Node<T> * right = NULL;
while(fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next;
fast = fast->next;
}
right = slow->next;
slow->next = NULL;
return right;
}
/*
* merge two sorted linked lists the return head to the sorted list
*/
template<typename T>
Node<T>* merge(Node<T>* left, Node<T>* right)
{
if(left == NULL)
return right;
if(right == NULL)
return left;
Node<T> *h = NULL;
if(left->data < right->data){
h = left;
left = left->next;
}
else{
h = right;
right = right->next;
}
Node<T>* t = h;
while(left != NULL && right != NULL)
{
if(left->data < right->data){
t->next = left;
left = left->next;
t = t->next;
}
else{
t->next = right;
right = right->next;
t = t->next;
}
}
// if any of the list has remaining nodes
if(left == NULL)
t->next = right;
else
t->next = left;
return h;
}
/*
* merge sort a linked list
*/
template<typename T>
void mergeSort(Node<T>** headref)
{
Node<T>* head= *headref;
if(head == NULL || (head)->next == NULL)
return;
Node<T>* left = head;
Node<T>* right = splitLinkedlist(left);
mergeSort(&left);
mergeSort(&right);
*headref = merge(left, right);
}
int main()
{
Node<int>* head = NULL;
pushToLinkedList(&head, 5);
pushToLinkedList(&head, 15);
pushToLinkedList(&head, 11);
pushToLinkedList(&head, 8);
pushToLinkedList(&head, 17);
pushToLinkedList(&head, -1);
pushToLinkedList(&head, 4);
pushToLinkedList(&head, 20);
pushToLinkedList(&head, 11);
/*
Node<string>* head = NULL;
pushToLinkedList(&head, string("David"));
pushToLinkedList(&head, string("Alice"));
pushToLinkedList(&head, string("Bob"));
*/
cout << "Original List:";
printLinkedList(head);
mergeSort(&head);
cout << "Sorted List:";
printLinkedList(head);
deleteLinkedList(head);
return 0;
}
Wednesday, May 22, 2013
Merge Sort a Linked List
Subscribe to:
Posts (Atom)