Generated on Mon Aug 25 11:35:44 2008 for Gecode by doxygen 1.5.6

sort.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2002
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-03-04 13:54:11 +0100 (Tue, 04 Mar 2008) $ by $Author: tack $
00011  *     $Revision: 6405 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include <algorithm>
00039 
00040 namespace Gecode { namespace Support {
00041 
00043   template <class Type, class LessThan>
00044   forceinline void
00045   exchange(Type &a, Type &b, LessThan &lt) {
00046     if (lt(b,a)) std::swap(a,b);
00047   }
00048 
00050   int const QuickSortCutoff = 20;
00051 
00053   template <class Type>
00054   class QuickSortStack {
00055   private:
00057     static const int maxsize = 32;
00059     Type** tos;
00061     Type*  stack[2*maxsize+1];
00062   public:
00064     QuickSortStack(void);
00066     bool empty(void) const;
00068     void push(Type* l, Type* r);
00070     void pop(Type*& l, Type*& r);
00071   };
00072 
00073   template <class Type>
00074   forceinline
00075   QuickSortStack<Type>::QuickSortStack(void) : tos(&stack[0]) {
00076     *(tos++) = NULL;
00077   }
00078 
00079   template <class Type>
00080   forceinline bool
00081   QuickSortStack<Type>::empty(void) const {
00082     return *(tos-1) == NULL;
00083   }
00084 
00085   template <class Type>
00086   forceinline void
00087   QuickSortStack<Type>::push(Type* l, Type* r) {
00088     *(tos++) = l; *(tos++) = r;
00089   }
00090 
00091   template <class Type>
00092   forceinline void
00093   QuickSortStack<Type>::pop(Type*& l, Type*& r) {
00094     r = *(--tos); l = *(--tos);
00095   }
00096 
00098   template <class Type, class LessThan>
00099   forceinline void
00100   insertion(Type* l, Type* r, LessThan &lt) {
00101     for (Type* i = r; i > l; i--)
00102       exchange(*(i-1),*i,lt);
00103     for (Type* i = l+2; i <= r; i++) {
00104       Type* j = i;
00105       Type v = *i;
00106       while (lt(v,*(j-1))) {
00107         *j = *(j-1); j--;
00108       }
00109       *j = v;
00110     }
00111   }
00112 
00114   template <class Type, class LessThan>
00115   forceinline Type*
00116   partition(Type* l, Type* r, LessThan &lt) {
00117     Type* i = l-1;
00118     Type* j = r;
00119     Type v = *r;
00120     while (true) {
00121       while (lt(*(++i),v)) {}
00122       while (lt(v,*(--j))) if (j == l) break;
00123         if (i >= j) break;
00124         std::swap(*i,*j);
00125     }
00126     std::swap(*i,*r);
00127     return i;
00128   }
00129 
00131   template <class Type, class LessThan>
00132   inline void
00133   quicksort(Type* l, Type* r, LessThan &lt) {
00134     QuickSortStack<Type> s;
00135     while (true) {
00136       std::swap(*(l+((r-l) >> 1)),*(r-1));
00137       exchange(*l,*(r-1),lt);
00138       exchange(*l,*r,lt);
00139       exchange(*(r-1),*r,lt);
00140       Type* i = partition(l+1,r-1,lt);
00141       if (i-l > r-i) {
00142         if (r-i > QuickSortCutoff) {
00143           s.push(l,i-1); l=i+1; continue;
00144         }
00145         if (i-l > QuickSortCutoff) {
00146           r=i-1; continue;
00147         }
00148       } else {
00149         if (i-l > QuickSortCutoff) {
00150           s.push(i+1,r); r=i-1; continue;
00151         }
00152         if (r-i > QuickSortCutoff) {
00153           l=i+1; continue;
00154         }
00155       }
00156       if (s.empty())
00157         break;
00158       s.pop(l,r);
00159     }
00160   }
00161 
00176   template <class Type, class LessThan>
00177   forceinline void
00178   insertion(Type* x, int n, LessThan &lt) {
00179     if (n < 2)
00180       return;
00181     insertion(x,x+n-1,lt);
00182   }
00183 
00198   template <class Type, class LessThan>
00199   forceinline void
00200   quicksort(Type* x, int n, LessThan &lt) {
00201     if (n < 2)
00202       return;
00203     if (n > QuickSortCutoff)
00204       quicksort(x,x+n-1,lt);
00205     insertion(x,x+n-1,lt);
00206   }
00207 
00208 }}
00209 
00210 // STATISTICS: support-any