00001
00002
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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef TPL_DYNMAPTREE_H
00045 # define TPL_DYNMAPTREE_H
00046
00047 # include <tpl_binNodeUtils.H>
00048
00049 using namespace Aleph;
00050
00051 namespace Aleph {
00052
00075 template <
00076 template <typename , class > class Tree,
00077 typename Key,
00078 typename Range,
00079 class Compare = Aleph::less<Key>
00080 >
00081 class DynMapTree
00082 {
00083 Tree<Key, Compare> tree;
00084 size_t num_nodes;
00085 struct Node : public Tree<Key, Compare>::Node
00086 {
00087
00088 friend class DynMapTree<Tree, Key, Range, Compare>;
00089
00090 Range data;
00091
00092 Node() { }
00093
00094 Node(const Key & _key) : Tree<Key, Compare>::Node(_key) { }
00095
00096 Range & get_data() { return data; }
00097 };
00098 class Proxy
00099 {
00100 DynMapTree & tree;
00101 const Key & key;
00102 Node * node;
00103
00104 public:
00105
00106 Proxy(DynMapTree & _tree, const Key &_key) : tree(_tree), key(_key)
00107 {
00108 node = static_cast<Node*>(tree.tree.search(key));
00109 }
00110
00111 Proxy & operator = (const Range & data)
00112 {
00113 if (node == NULL)
00114 {
00115 node = static_cast<Node*>(tree.tree.insert(new Node (key)));
00116
00117 tree.num_nodes++;
00118 }
00119
00120 node->get_data() = data;
00121
00122 return *this;
00123 }
00124
00125 Proxy& operator = (const Proxy & proxy)
00126 {
00127 if (this == &proxy)
00128 return *this;
00129
00130 if (proxy.node == NULL)
00131 throw std::domain_error("key not found");;
00132
00133 if (&tree == &proxy.tree and key == proxy.key)
00134 return *this;
00135
00136 if (node == NULL)
00137 {
00138 node = static_cast<Node*>(tree.tree.insert(new Node (key)));
00139
00140 tree.num_nodes++;
00141 }
00142
00143 node->get_data() = proxy.node->get_data();
00144
00145 return *this;
00146 }
00147
00148 operator Range & () const
00149 {
00150 if (node == NULL)
00151 throw std::domain_error("key not found");;
00152
00153 return node->get_data();
00154 }
00155 };
00156
00157 public:
00158
00160 const size_t & size() const { return num_nodes; }
00162 bool is_empty() const { return size() == 0; }
00164 DynMapTree() : num_nodes(0) { }
00165
00167 DynMapTree(DynMapTree & src_tree) : num_nodes(src_tree.num_nodes)
00168 {
00169 Node * src_root = static_cast<Node*>(src_tree.tree.getRoot());
00170
00171 try
00172 {
00173
00174
00175 tree.getRoot() = copyRec(src_root);
00176
00177 }
00178 catch (...)
00179 {
00180 num_nodes = 0;
00181 throw;
00182 }
00183
00184 }
00185
00187 virtual ~DynMapTree()
00188 {
00189 if (num_nodes > 0)
00190 destroyRec(tree.getRoot());
00191 }
00193 DynMapTree & operator = (DynMapTree & src_tree)
00194 {
00195 if (this == &src_tree)
00196 return *this;
00197
00198 Node * src_root = static_cast<Node*>(src_tree.tree.getRoot());
00199 Node * old_root = static_cast<Node*>(tree.getRoot());
00200
00201 tree.getRoot() = copyRec(src_root);
00202 num_nodes = src_tree.num_nodes;
00203
00204 destroyRec(old_root);
00205
00206 return *this;
00207 }
00219 size_t insert(const Key & key, const Range & data)
00220 {
00221 Node * node = new Node (key);
00222 node->data = data;
00223
00224 if (tree.insert(node) == NULL)
00225 {
00226 delete node;
00227 return num_nodes;
00228 }
00229
00230 return ++num_nodes;
00231 }
00240 size_t remove(const Key & key)
00241 {
00242 Node * node = static_cast<Node*>(tree.remove(key));
00243
00244 if (node == NULL)
00245 return num_nodes;
00246
00247 delete node;
00248
00249 return --num_nodes;
00250 }
00252 void empty()
00253 {
00254 num_nodes = 0;
00255 destroyRec(static_cast<Node*>(tree.getRoot()));
00256 }
00258 bool test_key(const Key & key)
00259 {
00260 Node * node = static_cast<Node*>(tree.search(key));
00261
00262 return node != NULL;
00263 }
00264
00274 Range * test(const Key & key)
00275 {
00276 Node * node = static_cast<Node*>(tree.search(key));
00277
00278 return node != NULL ? &(node->get_data()) : NULL;
00279 }
00280 Proxy operator [] (const Key & key) const
00281 Exception_Prototypes(std::domain_error)
00282 {
00283 return Proxy(*this, key);
00284 }
00285
00286 Proxy operator [] (const Key & key)
00287 Exception_Prototypes(std::domain_error)
00288 {
00289 return Proxy(*this, key);
00290 }
00292 size_t internal_path_length()
00293 {
00294 return Aleph::internal_path_length(tree.getRoot());
00295 }
00296
00298 size_t height() { return computeHeightRec(tree.getRoot()); }
00300 void for_each_in_preorder(void (*visitFct)(Node*, int, int))
00301 {
00302 Node * root = static_cast<Node*>(tree.getRoot());
00303
00304 preOrderRec(root, visitFct);
00305 }
00306
00308 void for_each_in_inorder(void (*visitFct)(Node*, int, int))
00309 {
00310 Node * root = static_cast<Node*>(tree.getRoot());
00311
00312 inOrderRec(root, visitFct);
00313 }
00314
00316 void for_each_in_postorder(void (*visitFct)(Node*, int, int))
00317 {
00318 Node * root = static_cast<Node*>(tree.getRoot());
00319
00320 postOrderRec(root, visitFct);
00321 }
00322
00324 void for_each(void (*visitFct)(Node*, int, int))
00325 {
00326 for_each_in_inorder(visitFct);
00327 }
00329 typedef Node Node_Type;
00330
00332 typedef Tree<Key, Compare> Tree_Type;
00334 const Key & get_key(Node_Type * p)
00335 {
00336 return p->get_key();
00337 }
00338
00340 Range & get_data(Node_Type * p)
00341 {
00342 return p->get_data();
00343 }
00344 };
00345
00346 }
00347
00348 # include <tpl_binTree.H>
00349 # include <tpl_avl.H>
00350 # include <tpl_rb_tree.H>
00351 # include <tpl_rand_tree.H>
00352 # include <tpl_treap.H>
00353 # include <tpl_splay_tree.H>
00354
00355 namespace Aleph {
00362 template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00363 class DynMapBinTree : public DynMapTree<BinTree, Key, Type, Compare>
00364 { };
00365
00372 template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00373 class DynMapAvlTree : public DynMapTree<Avl_Tree, Key, Type, Compare>
00374 { };
00381 template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00382 class DynMapRbTree : public DynMapTree<Rb_Tree, Key, Type, Compare>
00383 { };
00384
00392 template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00393 class DynMapRandTree : public DynMapTree<Rand_Tree, Key, Type, Compare>
00394 { };
00395
00402 template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00403 class DynMapTreap : public DynMapTree<Treap, Key, Type, Compare>
00404 { };
00405
00412 template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00413 class DynMapSplayTree : public DynMapTree<Splay_Tree, Key, Type, Compare>
00414 { };
00415
00416 }
00417
00418 # endif
00419