Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_union.H
1 # ifndef TPL_UNION_H
2 # define TPL_UNION_H
3 
4 # include <tpl_dynArray.H>
5 # include <tpl_dynSetTree.H>
6 
7 # define UNION_ATTRS \
8  DynArray<size_t> id; \
9  DynArray<size_t> sz; \
10  size_t num_blocks;
11 
12 # define UNION_ROOT_IMPL \
13  while (i != id(i)) \
14  { \
15  id(i) = id(id(i)); \
16  i = id(i); \
17  } \
18  \
19  return i;
20 
21 # define UNION_DEPTH \
22  size_t depth(size_t i) \
23  { \
24  const int & parent = id(i); \
25  \
26  if (parent == i) \
27  return 1; \
28  \
29  return 1 + depth(parent); \
30  }
31 
32 # define UNION_CTOR \
33  : num_blocks(n) \
34  { \
35  id.reserve(n); \
36  sz.reserve(n); \
37  \
38  for (int i = 0; i < n; ++i) \
39  { \
40  id(i) = i; \
41  sz(i) = 1; \
42  } \
43  }
44 
45 # define UNION_PUBLIC_ROUTINES \
46  size_t size() const { return id.size(); } \
47  \
48  size_t get_num_blocks() const { return num_blocks; } \
49  \
50  bool are_connected(size_t i, size_t j) \
51  { \
52  return root(i) == root(j); \
53  } \
54  \
55  void join(size_t i, size_t j) \
56  { \
57  i = root(i); \
58  j = root(j); \
59  if (i == j) \
60  return; \
61  \
62  if (sz(i) < sz(j)) \
63  { \
64  id(i) = j; \
65  sz(j) += sz(i); \
66  } \
67  else \
68  { \
69  id(j) = i; \
70  sz(i) += sz(j); \
71  } \
72  --num_blocks; \
73  }
74 
100 {
101  UNION_ATTRS
102 
103  size_t root(size_t i)
104  {
105  UNION_ROOT_IMPL
106  }
107 
108  UNION_DEPTH
109 
110 public:
111 
113  Fixed_Relation(size_t n) UNION_CTOR
114 
115  UNION_PUBLIC_ROUTINES
116 };
117 
118 
133 class Relation
134 {
135  UNION_ATTRS
136 
137  void verify_if_add_new_points(size_t n)
138  {
139  size_t l = size();
140  if (n < l)
141  return;
142 
143  id.reserve(l, n);
144  sz.reserve(l, n);
145  for (int i = l; i <= n; ++i)
146  {
147  id(i) = i;
148  sz(i) = 1;
149  }
150  num_blocks += n - l + 1;
151  }
152 
153  size_t root(size_t i)
154  {
155  verify_if_add_new_points(i);
156  UNION_ROOT_IMPL;
157  }
158 
159  UNION_DEPTH
160 
161 public:
162 
164  Relation(size_t n = 0) UNION_CTOR
165 
166  UNION_PUBLIC_ROUTINES
167 };
168 
169 
187  template <typename T, class Compare = Aleph::less<T>>
188 class Relation_T : public Relation
189 {
190  struct Pair
191  {
192  T item;
193  size_t i;
194 
195  Pair() {}
196 
197  Pair(const T & __item, size_t __i)
198  : item(__item), i(__i) { /* empty */ }
199  };
200 
201  struct Cmp
202  {
203  bool operator () (const Pair & p1, const Pair & p2) const
204  {
205  return Compare() (p1.item, p2.item);
206  }
207  };
208 
209  DynSetAvlTree<Pair, Cmp> items_tree;
210 
211  // retorna el id del item; sea porque lo encuentra o porque lo inserta
212  size_t test_and_insert_new_item(const T & item)
213  {
214  size_t N = size();
215  Pair p(item, N);
216  Pair * ptr = items_tree.search_or_insert(p);
217  return ptr->i;
218  }
219 
220 public:
221 
223  bool are_connected(const T & p, const T & q)
224  {
225  size_t i = test_and_insert_new_item(p);
226  size_t j = test_and_insert_new_item(q);
227 
228  return Relation::are_connected(i, j);
229  }
230 
232  void join(const T & p, const T & q)
233  {
234  size_t i = test_and_insert_new_item(p);
235  size_t j = test_and_insert_new_item(q);
236  Relation::join(i, j);
237  }
238 };
239 
240 # endif // TPL_UNION_H
Definition: tpl_union.H:133
Definition: tpl_union.H:99
Node * join(Node *t1, Node *t2, Node *&dup)
Definition: tpl_binNodeUtils.H:2337
bool are_connected(const T &p, const T &q)
Retorna true is i y j están conectados.
Definition: tpl_union.H:223
void join(const T &p, const T &q)
Une p con q.
Definition: tpl_union.H:232
Definition: tpl_union.H:188
Key * search_or_insert(const Key &key)
Definition: tpl_dynSetTree.H:225

Leandro Rabindranath León