00001 #ifndef __MX__TREE_H_
00002 #define __MX__TREE_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include<iostream>
00033 #include<cstdlib>
00034
00035 namespace mx
00036 {
00037
00038 template<typename Key, typename Value>
00039 class mxNode {
00040 public:
00041 mxNode() { left = right = 0; }
00042 mxNode( Key k, Value v )
00043 {
00044 key = k;
00045 value = v;
00046 left = right = 0;
00047 }
00048
00049 ~mxNode()
00050 {
00051 if(left) delete left;
00052 if(right) delete right;
00053 left = 0;
00054 right = 0;
00055 }
00056
00057 Value value;
00058 Key key;
00059 mxNode *left, *right;
00060 };
00061
00062
00063 template<typename Key, typename Value>
00064 class mxList {
00065
00066 public:
00067
00068 mxList() : head(0) { }
00069
00070
00071 mxList( mxList<Key, Value> &lst );
00072
00073 ~mxList();
00074
00075 mxNode<Key,Value> *addItem( Key k, Value val );
00076 Value &operator[]( Key k );
00077 Value *operator()( Key k );
00078
00079 mxList<Key,Value> &operator=( mxList<Key,Value> &lst );
00080 mxList<Key,Value> &operator+=( mxList<Key,Value> &lst ) { concatList(lst); return *this; }
00081 void concatList( mxList<Key,Value> &lst );
00082 void clear();
00083 void removeItem( Key k );
00084
00085 void printNode( mxNode<Key,Value> *n);
00086 void printNode();
00087
00088
00089 mxNode<Key,Value> *root() const { return head; }
00090 mxNode<Key,Value> *find( Key k );
00091
00092
00093 protected:
00094 mxNode<Key,Value> *head;
00095 void catNode( mxNode<Key,Value> *n );
00096 void nocatNode( mxNode<Key,Value> *n, Key k );
00097
00098 };
00099
00100
00101 template<typename Key, typename Value>
00102 mxList<Key,Value>::mxList( mxList<Key, Value> &lst ) : head(0)
00103 {
00104 clear();
00105 concatList( lst );
00106
00107 }
00108
00109 template<typename Key, typename Value>
00110 mxNode<Key,Value> *mxList<Key,Value>::addItem( Key k, Value value )
00111 {
00112 if(head == 0)
00113 {
00114 head = new mxNode<Key,Value>(k,value);
00115 return head;
00116
00117 }
00118
00119 mxNode<Key,Value> **ptr = &head, *p;
00120
00121 while ( ( p = *ptr ) != 0 )
00122 {
00123 if(p->key == k) return p;
00124 if( (p->key > k) == 0 ) ptr = &p->left; else ptr = &p->right;
00125 }
00126
00127 p = new mxNode<Key,Value>(k,value);
00128 *ptr = p;
00129
00130 return p;
00131 }
00132
00133 template<typename Key, typename Value>
00134 mxNode<Key,Value> *mxList<Key,Value>::find( Key k )
00135 {
00136
00137 if(head == 0) return 0;
00138
00139 mxNode<Key,Value> **ptr = &head, *p;
00140
00141 while( ( p = *ptr ) != 0 )
00142 {
00143
00144 if(p->key == k) return p;
00145 if((p->key > k) == 0) ptr = &p->left; else ptr = &p->right;
00146 }
00147 return 0;
00148 }
00149
00150 template<typename Key, typename Value>
00151 mxList<Key, Value>::~mxList()
00152 {
00153
00154 clear();
00155
00156 }
00157
00158 template<typename Key, typename Value>
00159 void mxList<Key,Value>::clear()
00160 {
00161
00162 if(head)
00163 delete head;
00164 head = 0;
00165
00166 }
00167
00168 template<typename Key, typename Value>
00169 void mxList<Key,Value>::printNode( mxNode<Key,Value> *n)
00170 {
00171
00172
00173 if(n->left) printNode(n->left);
00174 if(n->right) printNode(n->right);
00175
00176 std::cout << "Node: " << n->key << " : " << n->value << "\n";
00177 }
00178
00179 template<typename Key, typename Value>
00180 void mxList<Key,Value>::printNode()
00181 {
00182
00183 if(root())
00184 printNode(root());
00185
00186 }
00187
00188 template<typename Key, typename Value>
00189 Value &mxList<Key,Value>::operator[]( Key k )
00190 {
00191
00192 mxNode<Key,Value> *node_ptr;
00193
00194 node_ptr = this->find(k);
00195
00196 Value v;
00197 if(node_ptr == 0) return addItem(k, v)->value;
00198
00199 return node_ptr->value;
00200 }
00201
00202 template<typename Key, typename Value>
00203 Value *mxList<Key,Value>::operator()( Key k )
00204 {
00205 mxNode<Key,Value> *node_ptr;
00206 node_ptr = this->find(k);
00207 if(node_ptr == 0) return 0;
00208 return &node_ptr->value;
00209 }
00210
00211 template<typename Key, typename Value>
00212 void mxList<Key,Value>::concatList( mxList<Key,Value> &lst )
00213 {
00214 if(lst.root())
00215 catNode( lst.root() );
00216 }
00217
00218 template<typename Key, typename Value>
00219 void mxList<Key,Value>::catNode( mxNode<Key,Value> *n )
00220 {
00221
00222 if(n->left) catNode(n->left);
00223 if(n->right) catNode(n->right);
00224
00225 addItem(n->key, n->value);
00226
00227 }
00228
00229 template<typename Key, typename Value>
00230 void mxList<Key,Value>::nocatNode( mxNode<Key,Value> *n, Key k )
00231 {
00232
00233 if(n->left) nocatNode(n->left, k);
00234 if(n->right) nocatNode(n->right, k);
00235
00236 if(n->key != k)
00237 addItem(n->key, n->value);
00238 }
00239
00240 template<typename Key, typename Value>
00241 void mxList<Key,Value>::removeItem ( Key k )
00242 {
00243 mxList<Key,Value> lst(*this);
00244 clear();
00245
00246 if(lst.root())
00247 nocatNode( lst.root(), k);
00248 }
00249
00250
00251 template<typename Key, typename Value>
00252 mxList<Key,Value> &mxList<Key,Value>::operator=( mxList<Key,Value> &lst )
00253 {
00254 clear();
00255 concatList( lst );
00256 return *this;
00257 }
00258
00259
00260
00261
00262 template<typename Type, typename Accum, size_t HASH_SIZE>
00263 Accum HashKey(Type t)
00264 {
00265 size_t i = 0;
00266 Accum h = Accum(), g = Accum();
00267
00268 for(i = 0; t[i] != 0; i++)
00269 {
00270 h = ( h << 4 ) + ( t[i] );
00271 if( (g = h&0xF0000000) )
00272 {
00273 h = h ^ (g >> 24);
00274 h = h ^ g;
00275 }
00276 }
00277
00278 return (h%HASH_SIZE);
00279 }
00280
00281
00282 template<size_t HASH_SIZE, typename InputIterator, typename Return>
00283 Return HashKey(InputIterator begin, InputIterator end)
00284 {
00285 Return h = Return(), g = Return();
00286 InputIterator i;
00287 for(i = begin; i != end; i++)
00288 {
00289 h = ( h << 4 ) + ( *i );
00290 if( (g = h&0xF0000000) )
00291 {
00292 h = h ^ (g >> 24);
00293 h = h ^ g;
00294 }
00295 }
00296 return (h%HASH_SIZE);
00297 }
00298
00299
00300 template<typename String>
00301 unsigned int HashKey(String key, unsigned int size)
00302 {
00303
00304 unsigned int i = 0, h = 0, g = 0;
00305 for(i = 0; key[i] != 0; i++)
00306 {
00307 h = ( h << 4 ) + ( key[i] );
00308 if( (g = h&0xF0000000) )
00309 {
00310 h = h ^ (g >> 24);
00311 h = h ^ g;
00312 }
00313 }
00314 return (h%size);
00315 }
00316
00317
00318
00319 }
00320
00321
00322
00323
00324 #endif
00325