Created
April 3, 2011 11:23
-
-
Save hpcx82/900369 to your computer and use it in GitHub Desktop.
quick sort of single linked list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <utility> | |
// | |
// Quick sort for single linked list | |
// | |
// Template arguments: | |
// T: node's pointer type | |
// Next: function/functor to get next node | |
// Compare: functor to compare 2 arguments | |
// | |
// Functions: | |
// partition: partition the list into 2 parts, with the pivot at the middle | |
// quick_sort: recurisve sort left and right part | |
// | |
template <class T, class Next, class Compare> | |
std::pair<T, T> partition(T start, T end, Next next, Compare comp) | |
{ | |
// use the first element as pivot as it is easier to access | |
T pivot = start; | |
// in process of partition, there are 4 part of datas: | |
// pivot | less than pivot | larger than pivot | not processed | | |
// | |
// first, initialize sLast and lLast to the pivot | |
T sLast = start; | |
T lLast = start; | |
// start to process each element after pivot | |
T iter = next(start); | |
while(iter != end) | |
{ | |
T cur = iter; | |
iter = next(iter); | |
if(comp(cur, pivot)) | |
{ | |
// insert current to the next of sLast, only if we already have some elements larger than pivot | |
if(lLast != pivot) | |
{ | |
// insert after sLast | |
T temp = next(sLast); | |
next(sLast) = cur; | |
next(cur) = temp; | |
// as cur is removed, we need to link the 2 node before and after | |
next(lLast) = iter; | |
} | |
// advance sLast | |
sLast = cur; | |
} | |
else | |
{ | |
// advance lLast | |
lLast = cur; | |
} | |
} | |
T head = next(pivot); | |
// Insert pivot to the correct position if there is no element less than pivot | |
if(sLast != pivot) | |
{ | |
T temp = next(sLast); | |
next(sLast) = pivot; | |
next(pivot) = temp; | |
} | |
return std::make_pair(head ,pivot); | |
} | |
// TODO: merge sort, insert sort! and compare them | |
template <class T, class Next, class Compare> | |
T quick_sort(T start, T end, Next next, Compare comp) | |
{ | |
// base case - only one element in the list | |
if(start == end) return start; | |
if(start != NULL && next(start) == end) return start; | |
if(end != NULL && next(end) == start) return end; // think about already sorted list | |
// divide | |
std::pair<T, T> pos = partition(start, end, next, comp); | |
// and conquer | |
T head1 = quick_sort(pos.first, pos.second, next, comp); | |
T head2 = quick_sort(next(pos.second), end, next, comp); | |
// link the first part and the second part, or else you may drop some elements | |
next(pos.second) = head2; | |
return head1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment