00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __GECODE_SUPPORT_SORT_HH__
00023 #define __GECODE_SUPPORT_SORT_HH__
00024
00025 #include <algorithm>
00026
00027 namespace Gecode { namespace Support {
00028
00030 template <class Type, class LessThan>
00031 forceinline void
00032 exchange(Type &a, Type &b, LessThan <) {
00033 if (lt(b,a)) std::swap(a,b);
00034 }
00035
00037 int const QuickSortCutoff = 20;
00038
00040 static const int QuickSortStack_maxsize = 32;
00041
00043 template <class Type>
00044 class QuickSortStack {
00045 private:
00046 Type** tos;
00047 Type* stack[2*QuickSortStack_maxsize];
00048 public:
00049 QuickSortStack(void);
00050 bool empty(void) const;
00051 void push(Type*, Type*);
00052 void pop(Type*&, Type*&);
00053 };
00054
00055 template <class Type>
00056 forceinline
00057 QuickSortStack<Type>::QuickSortStack(void) : tos(&stack[0]) {
00058 *(tos++) = 0;
00059 }
00060
00061 template <class Type>
00062 forceinline bool
00063 QuickSortStack<Type>::empty(void) const {
00064 return !*(tos-1);
00065 }
00066
00067 template <class Type>
00068 forceinline void
00069 QuickSortStack<Type>::push(Type* l, Type* r) {
00070 *(tos++) = l; *(tos++) = r;
00071 }
00072
00073 template <class Type>
00074 forceinline void
00075 QuickSortStack<Type>::pop(Type*& l, Type*& r) {
00076 r = *(--tos); l = *(--tos);
00077 }
00078
00080 template <class Type, class LessThan>
00081 inline void
00082 insertion(Type* l, Type* r, LessThan <) {
00083 for (Type* i = r; i > l; i--)
00084 exchange(*(i-1),*i,lt);
00085 for (Type* i = l+2; i <= r; i++) {
00086 Type* j = i;
00087 Type v = *i;
00088 while (lt(v,*(j-1))) {
00089 *j = *(j-1); j--;
00090 }
00091 *j = v;
00092 }
00093 }
00094
00096 template <class Type, class LessThan>
00097 inline Type*
00098 partition(Type* l, Type* r, LessThan <) {
00099 Type* i = l-1;
00100 Type* j = r;
00101 Type v = *r;
00102 while (true) {
00103 while (lt(*(++i),v));
00104 while (lt(v,*(--j))) if (j == l) break;
00105 if (i >= j) break;
00106 std::swap(*i,*j);
00107 }
00108 std::swap(*i,*r);
00109 return i;
00110 }
00111
00113 template <class Type, class LessThan>
00114 inline void
00115 quicksort(Type* l, Type* r, LessThan <) {
00116 QuickSortStack<Type> s;
00117 s.push(l,r);
00118 while (!s.empty()) {
00119 s.pop(l,r);
00120 nopush:
00121 if (r-l <= QuickSortCutoff)
00122 continue;
00123 std::swap(*(l+((r-l) >> 1)),*(r-1));
00124 exchange(*l,*(r-1),lt);
00125 exchange(*l,*r,lt);
00126 exchange(*(r-1),*r,lt);
00127 Type* i = partition(l+1,r-1,lt);
00128 if (i-l > r-i) {
00129 s.push(l,i-1); l=i+1; goto nopush;
00130 } else {
00131 s.push(i+1,r); r=i-1; goto nopush;
00132 }
00133 }
00134 }
00135
00136
00137
00138
00139
00140
00156 template <class Type, class LessThan>
00157 forceinline void
00158 insertion(Type* x, int n, LessThan <) {
00159 if (n < 2)
00160 return;
00161 insertion(x,x+n-1,lt);
00162 }
00163
00179 template <class Type, class LessThan>
00180 forceinline void
00181 quicksort(Type* x, int n, LessThan <) {
00182 if (n < 2)
00183 return;
00184 if (n > QuickSortCutoff)
00185 quicksort(x,x+n-1,lt);
00186 insertion(x,x+n-1,lt);
00187 }
00188
00189 }}
00190
00191 #endif
00192
00193