Files Classes Functions Hierarchy
00001 #ifndef BUCKET_H 00002 #define BUCKET_H 00003 00004 #include <cassert> 00005 using namespace std; 00006 00007 00008 #include <bucketlink.h> 00009 #include <typedefs.h> 00010 00011 00012 /* 00013 \brief Implement generic bucket sort for attempted O(n) sorting. 00014 Worst Case is O(n^2). The bucket allows for duplicate data. 00015 00016 The bucket size is passed through the function and must 00017 be >= datasz. 00018 00019 00020 \verbatim 00021 Interface for template HFN parameter 00022 00023 class HFN 00024 { 00025 public: 00026 00027 // Configures the number of buckets. 00028 uint bucketsize; 00029 // Decide which bucket the data belongs. 00030 uintc index(T const &) const; 00031 // Comparision for sorting 00032 bool const operator()(T const & a, T const & b); 00033 }; 00034 \endverbatim 00035 00036 \par Example 00037 \verbatim 00038 vector<double> v(n); 00039 fill(&v[0],n); 00040 00041 unitdouble f1(2*n); 00042 bucket<double,unitdouble> b(&v[0],n,f1); 00043 b.eval(); 00044 \endverbatim 00045 00046 Issues: I chose not to use STL for I may need perhaps hundreds 00047 of thousands of lists and I do not know how lightweight STL is. 00048 Equal elements are unfortunately inserted last. 00049 */ 00050 template< typename T, typename HFN > 00051 class bucket 00052 { 00053 protected: 00055 T * data; 00057 uintc datasz; 00059 HFN fn; 00061 bucketlink<T> * * vb; 00063 bucketlink<T> * link; 00065 uint linki; 00066 public: 00067 00070 bucket 00071 ( 00072 T * data_, 00073 uintc datasz_, 00074 HFN fn_ 00075 ); 00077 ~bucket(); 00078 00080 void eval(); 00082 void copy(T * data2) const; 00083 00084 }; 00085 00086 00087 //--------------------------------------------------------- 00088 // Implementation 00089 00090 00091 template< typename T, typename HFN > 00092 void bucket<T,HFN>::copy(T * data2) const 00093 { 00094 assert(data2!=data); 00095 00096 bucketlink<T> * cp; 00097 00098 for (uint i=0; i<fn.bucketsize; ++i) 00099 { 00100 cp = vb[i]; 00101 if (cp==0) 00102 continue; 00103 00104 for (;cp!=0;) 00105 { 00106 *data2++ = *(cp->data); 00107 cp = cp->next; 00108 } 00109 } 00110 00111 } 00112 00113 template< typename T, typename HFN > 00114 void bucket<T,HFN>::eval() 00115 { 00116 bucketlink<T> * cp; 00117 bucketlink<T> * b; 00118 uint k; 00119 // Insert data into the structure. 00120 for (uint i=0; i<datasz; ++i ) 00121 { 00122 b = & link[i]; 00123 b->data = & data[i]; 00124 00125 k = fn.index(*b->data); 00126 assert(k<fn.bucketsize); 00127 k = k % fn.bucketsize; 00128 00129 cp = vb[k]; 00130 if (cp==0) 00131 { 00132 vb[k] = b; 00133 continue; 00134 } 00135 00136 if ( fn(*(b->data),*(cp->data)) ) 00137 { 00138 b->next = cp; 00139 vb[k] = b; 00140 } 00141 else 00142 cp->insertafterself(b,fn); 00143 } 00144 } 00145 00146 00147 00148 00149 template< typename T, typename HFN > 00150 bucket<T,HFN>::bucket 00151 ( 00152 T *data_, 00153 uintc datasz_, 00154 HFN fn_ 00155 ) : 00156 data(data_), 00157 datasz(datasz_), 00158 fn(fn_) 00159 { 00160 assert(fn.bucketsize >= datasz); 00161 00162 link = new bucketlink<T>[datasz]; 00163 00164 vb = new bucketlink<T> * [fn.bucketsize]; 00165 for (uint i=0; i<fn.bucketsize; ++i) 00166 vb[i] = 0; 00167 } 00168 00169 template< typename T, typename HFN > 00170 bucket<T,HFN>::~bucket() 00171 { 00172 delete[] link; 00173 delete[] vb; 00174 00175 link = 0; 00176 vb = 0; 00177 } 00178 00179 00180 00181 00182 00183 #endif 00184 00185
1.5.8