aboutsummaryrefslogtreecommitdiff
path: root/common/algorithm.h
diff options
context:
space:
mode:
authorVladimir Menshakov2009-12-27 13:19:44 +0000
committerVladimir Menshakov2009-12-27 13:19:44 +0000
commit668ecc5d387e8acd7fd03a31fbabd062c76c8af7 (patch)
treea8f99ceabef4fcd660e192f6e9924aac18a20500 /common/algorithm.h
parentfabe51c129ef9d85e6f3c0f73ad16e66f7b3623b (diff)
downloadscummvm-rg350-668ecc5d387e8acd7fd03a31fbabd062c76c8af7.tar.gz
scummvm-rg350-668ecc5d387e8acd7fd03a31fbabd062c76c8af7.tar.bz2
scummvm-rg350-668ecc5d387e8acd7fd03a31fbabd062c76c8af7.zip
replaced bubble sort with quick sort
added distance(a, b) functions svn-id: r46638
Diffstat (limited to 'common/algorithm.h')
-rw-r--r--common/algorithm.h100
1 files changed, 63 insertions, 37 deletions
diff --git a/common/algorithm.h b/common/algorithm.h
index 01042536f6..1860e7a070 100644
--- a/common/algorithm.h
+++ b/common/algorithm.h
@@ -26,6 +26,7 @@
#define COMMON_ALGORITHM_H
#include "common/scummsys.h"
+#include "common/func.h"
namespace Common {
@@ -145,57 +146,82 @@ Op for_each(In first, In last, Op f) {
return f;
}
-/**
- * Simple sort function, modeled after std::sort.
- * Use it like this: sort(container.begin(), container.end()).
- * Also works on plain old i.e. int arrays etc. For comperance
- * operator < is used.
- */
-template<class T>
-void sort(T first, T last) {
- if (first == last)
- return;
+template<typename T>
+unsigned distance(T* first, T* last) {
+ return last - first;
+}
+
+template<typename T>
+unsigned distance(T first, T last) {
+ unsigned n = 0;
+ while(first != last) {
+ ++n;
+ ++first;
+ }
+ return n;
+}
+
+template<typename T>
+T* _sort_choose_pivot(T* first, T* last) {
+ return first + distance(first, last) / 2;
+}
+
+template<typename T>
+T _sort_choose_pivot(T first, T last) {
+ unsigned n = distance(first, last);
+ n /= 2;
+ while(n--)
+ ++first;
+ return first;
+}
- // Simple selection sort
- T i(first);
- for (; i != last; ++i) {
- T minElem(i);
- T j(i);
- ++j;
- for (; j != last; ++j)
- if (*j < *minElem)
- minElem = j;
- if (minElem != i)
- SWAP(*minElem, *i);
+template<typename T, class StrictWeakOrdering>
+T _sort_partition(T first, T last, T pivot, StrictWeakOrdering &comp) {
+ --last;
+ SWAP(*pivot, *last);
+
+ T sorted;
+ for(sorted = first; first != last; ++first) {
+ if (!comp(*last, *first)) {
+ if (first != sorted)
+ SWAP(*first, *sorted);
+ ++sorted;
+ }
}
+
+ SWAP(*last, *sorted);
+ return sorted;
}
/**
* Simple sort function, modeled after std::sort.
* It compares data with the given comparator object comp.
- *
- * Note: Using this with: Common::Less from common/func.h
- * will give the same results as the plain sort function.
*/
-template<class T, class StrictWeakOrdering>
+
+template<typename T, class StrictWeakOrdering>
void sort(T first, T last, StrictWeakOrdering comp) {
if (first == last)
return;
- // Simple selection sort
- T i(first);
- for (; i != last; ++i) {
- T minElem(i);
- T j(i);
- ++j;
- for (; j != last; ++j)
- if (comp(*j, *minElem))
- minElem = j;
- if (minElem != i)
- SWAP(*minElem, *i);
- }
+ T pivot = _sort_choose_pivot(first, last);
+ pivot = _sort_partition(first, last, pivot, comp);
+ sort<T, StrictWeakOrdering>(first, pivot, comp);
+ sort<T, StrictWeakOrdering>(++pivot, last, comp);
}
+/**
+ * Simple sort function, modeled after std::sort.
+ * Use it like this: sort(container.begin(), container.end()).
+ */
+
+template<typename T>
+void sort(T* first, T* last) {
+ sort(first, last, Common::Less<T>());
+}
+
+///\todo add value_type to all iterators and add default sort variant with Common::Less<T::value_type>()
+
+
} // End of namespace Common
#endif