Elm  1.0
ELM is a library providing generic data structures, OS-independent interface, plugins and XML.
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
GenTree.h
1 /*
2  * avl::GenTree class interface
3  *
4  * This file is part of OTAWA
5  * Copyright (c) 2008, IRIT UPS.
6  *
7  * OTAWA is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * OTAWA is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with OTAWA; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 #ifndef ELM_AVL_GENTREE_H
22 #define ELM_AVL_GENTREE_H
23 
24 #include <elm/utility.h>
25 #include <elm/PreIterator.h>
26 #include <elm/adapter.h>
27 #include <elm/util/array.h>
28 #include <elm/genstruct/Vector.h>
29 
30 namespace elm { namespace avl {
31 
32 // Private class
33 class AbstractTree {
34 protected:
35  inline AbstractTree(void): root(0), cnt(0) { }
36 
37  class Node {
38  public:
39  inline Node(void): balance(0) { links[0] = links[1] = 0; }
40  Node *links[2];
41  signed char balance;
42  };
43 
44  void insert(unsigned char da[], int dir, Node *node, Node *q, Node *y, Node *z);
45  void remove(Node *pa[], unsigned char da[], int k, Node *p);
46  int count(void) const;
47 
49  int cnt;
50 };
51 
52 // GenAVLTree class
53 template <class T, class K = IdAdapter<T>, class C = elm::Comparator<typename K::key_t> >
54 class GenTree: public AbstractTree {
55  static const int MAX_HEIGHT = 32;
56 protected:
57  class Node: public AbstractTree::Node {
58  public:
59  inline Node(const T& item): data(item) { }
60  inline Node(const Node *node): data(node->data) { }
61  T data;
62  inline Node *left(void) const { return (Node *)links[0]; }
63  inline Node *right(void) const { return (Node *)links[1]; }
64  inline Node *succ(int dir) const { return (Node *)links[dir]; }
65 # ifdef ELM_DEBUG_AVL
66  void dump(io::Output& out, int t) {
67  for(int i = 0; i < t; i++) out << " ";
68  out << data;
69  if(left()) left()->dump(out, t + 1);
70  if(right()) right()->dump(out, t + 1);
71  }
72 # endif
73  };
74 
75  Node *find(const typename K::key_t& key) const {
76  for(Node *p = (Node *)root; p;) {
77  int cmp = C::compare(key, K::key(p->data));
78  if(cmp < 0)
79  p = p->left();
80  else if(cmp > 0)
81  p = p->right();
82  else
83  return p;
84  }
85  return 0;
86  }
87 
88 public:
89 
90  GenTree(void) { }
91  GenTree(const GenTree<T>& tree) { copy(tree); }
92  ~GenTree(void) { clear(); }
93 
94 # ifdef ELM_DEBUG_AVL
95  void dump(io::Output& out) { if(root) static_cast<Node *>(root)->dump(out, 0); else out << "<empty>"; }
96 # endif
97  inline T *get(const typename K::key_t& key)
98  { Node *node = find(key); if(!node) return 0; else return &node->data; }
99  inline const T *get(const typename K::key_t& key) const
100  { const Node *node = find(key); if(!node) return 0; else return &node->data; }
101 
102  // Collection concept
103  inline int count(void) const { return cnt; }
104  inline bool contains(const typename K::key_t& item) const { return find(item) != 0; }
105  inline bool isEmpty(void) const { return cnt == 0; }
106  inline operator bool(void) const { return !isEmpty(); }
107 
108  template <template <class _> class Co>
109  inline bool containsAll(const Co<T>& coll) const
110  { for(typename Co<T>::Iterator iter(coll); iter; iter++)
111  if(!contains(iter)) return false; return true; }
112 
113  // Iterator class
114  class Iterator: public PreIterator<Iterator, const T&> {
115  public:
116  inline Iterator(const GenTree<T, K, C>& tree): sp(stack)
117  { if(tree.root) visit((Node *)tree.root); }
118  inline Iterator(const Iterator& iter): sp(stack + (iter.sp - iter.stack))
119  { array::copy(stack, iter.stack, iter.sp - iter.stack); }
120  inline bool ended(void) const { return sp == stack; }
121  void next(void) {
122  while(true) {
123  Node *last = pop();
124  if(ended()) return;
125  if(last == top()->left()) { push(top()); break; }
126  else if(last == top() && top()->right()) { visit(top()->right()); break; }
127  }
128  }
129  inline const T& item(void) const { return top()->data; }
130 
131  protected:
132  inline T& data(void) { return top()->data; }
133 
134  private:
135  inline void push(Node *node) { *sp++ = node; }
136  inline Node *pop(void) { return *--sp; }
137  inline Node *top(void) const { return sp[-1]; }
138  void visit(Node *node) {
139  if(!node) return;
140  push(node);
141  while(top()->left()) push(top()->left());
142  push(top());
143  }
144  Node *stack[MAX_HEIGHT + 1], **sp;
145  };
146 
147  // MutableCollection concept
148  void clear(void) {
149  Node *stack[MAX_HEIGHT + 1];
150  Node **sp = stack;
151  if(root)
152  *sp++ = static_cast<Node *>(root);
153  while(sp != stack) {
154  Node *node = *--sp;
155  if(node->left()) *sp++ = node->left();
156  if(node->right()) *sp++ = node->right();
157  delete node;
158  }
159  root = 0;
160  cnt = 0;
161  }
162 
163  void copy(const GenTree<T, K, C>& tree) {
164  clear();
165  Pair<Node *, AbstractTree::Node **> stack[MAX_HEIGHT + 1], *sp = stack;
166  if(tree.root)
167  *sp++ = pair(static_cast<Node *>(tree.root), &root);
168  while(sp != stack) {
170  Node *node = new Node(c.fst);
171  *c.snd = node;
172  if(c.fst->left()) *sp++ = pair(c.fst->left(), &node->links[0]);
173  if(c.fst->right()) *sp++ = pair(c.fst->right(), &node->links[1]);
174  }
175  cnt = tree.cnt;
176  }
177  inline GenTree<T, K, C>& operator=(const GenTree<T, K, C>& tree) { copy(tree); return *this; }
178 
179  void add(const T& item) {
180  unsigned char da[MAX_HEIGHT];
181  int k = 0;
182  Node *z = (Node *)&root;
183  Node *y = (Node *)root, *q, *p;
184 
185  // finding the insertion position
186  unsigned char dir = 0;
187  for(q = z, p = y; p != 0; q = p, p = p->succ(dir)) {
188  int cmp = C::compare(K::key(item), K::key(p->data));
189  if(p->balance != 0) {
190  z = q;
191  y = p;
192  k = 0;
193  }
194  dir = cmp > 0;
195  da[k++] = dir;
196  }
197 
198  // node creation
199  Node *node = new Node(item);
200  AbstractTree::insert(da, dir, node, q, y, z);
201  }
202 
203  void set(const T& item) {
204  unsigned char da[MAX_HEIGHT];
205  int k = 0;
206  Node *z = (Node *)&root;
207  Node *y = (Node *)root, *q, *p;
208 
209  // finding the insertion position
210  unsigned char dir = 0;
211  for(q = z, p = y; p != 0; q = p, p = p->succ(dir)) {
212  int cmp = C::compare(K::key(item), K::key(p->data));
213  if(cmp == 0) {
214  p->data = item;
215  return;
216  }
217  if(p->balance != 0) {
218  z = q;
219  y = p;
220  k = 0;
221  }
222  dir = cmp > 0;
223  da[k++] = dir;
224  }
225 
226  // node creation
227  Node *node = new Node(item);
228  AbstractTree::insert(da, dir, node, q, y, z);
229  }
230 
231  void remove(const typename K::key_t& item) {
232  AbstractTree::Node *pa[MAX_HEIGHT];
233  unsigned char da[MAX_HEIGHT];
234  int k;
235 
236  // find the item
237  k = 0;
238  Node *p = static_cast<Node *>(root);
239  for(int cmp = C::compare(item, K::key(p->data));
240  cmp != 0;
241  cmp = C::compare(item, K::key(p->data))) {
242  int dir = cmp > 0;
243  pa[k] = p;
244  da[k++] = dir ;
245  p = p->succ(dir);
246  ASSERTP(!p, "removed item not in the tree");
247  }
248 
249  // remove the item
250  AbstractTree::remove(pa, da, k, p);
251  delete p;
252  cnt--;
253  }
254 
255  inline void remove(const Iterator& iter) { remove(iter.item()); }
256  template <class CC> inline void addAll(const CC& coll)
257  { for(typename CC::Iterator iter(coll); iter; iter++) add(iter); }
258  template <class CC> inline void removeAll(const CC& coll)
259  { for(typename CC::Iterator iter(coll); iter; iter++) remove(iter); }
260 
261  bool equals(const GenTree<T, K, C>& tree) const {
262  GenTree<T, K, C>:: Iterator ai(*this), bi(tree);
263  for(; ai && bi; ai++, bi++)
264  if(!(C::compare(*ai, *bi) == 0))
265  return false;
266  return !ai && !bi;
267  }
268  inline bool operator==(const GenTree<T, K, C>& tree) const { return equals(tree); }
269  inline bool operator!=(const GenTree<T, K, C>& tree) const { return !equals(tree); }
270 };
271 
272 } } // elm::avl
273 
274 #endif // ELM_AVL_GENTREE_H
Iterator(const Iterator &iter)
Definition: GenTree.h:118
void copy(T *target, const T *source, int size)
Definition: array.h:59
void clear(void)
Definition: GenTree.h:148
Definition: PreIterator.h:29
Node(const Node *node)
Definition: GenTree.h:60
Node * left(void) const
Definition: GenTree.h:62
Node * root
Definition: GenTree.h:48
Definition: GenTree.h:57
int count(void) const
Definition: GenTree.h:103
int cnt
Definition: GenTree.h:49
Definition: Output.h:161
Pair< T1, T2 > pair(const T1 &v1, const T2 &v2)
Definition: Pair.h:41
Definition: GenTree.h:37
void next(void)
Definition: GenTree.h:121
void insert(unsigned char da[], int dir, Node *node, Node *q, Node *y, Node *z)
Definition: avl_GenTree.cpp:31
T data
Definition: GenTree.h:61
~GenTree(void)
Definition: GenTree.h:92
IntFormat right(IntFormat fmt)
Definition: Output.h:250
bool ended(void) const
Definition: GenTree.h:120
void copy(const GenTree< T, K, C > &tree)
Definition: GenTree.h:163
void remove(Node *pa[], unsigned char da[], int k, Node *p)
Definition: avl_GenTree.cpp:98
AbstractTree(void)
Definition: GenTree.h:35
GenTree(const GenTree< T > &tree)
Definition: GenTree.h:91
const T & item(void) const
Definition: GenTree.h:129
T1 fst
Definition: Pair.h:18
static void dump(Tree::Node *node, int tab=0)
Definition: avl_Tree.cpp:64
signed char balance
Definition: GenTree.h:41
void removeAll(const CC &coll)
Definition: GenTree.h:258
bool operator==(const GenTree< T, K, C > &tree) const
Definition: GenTree.h:268
Node * right(void) const
Definition: GenTree.h:63
Node * find(const typename K::key_t &key) const
Definition: GenTree.h:75
Node(void)
Definition: GenTree.h:39
sys::SystemOutStream & out
Definition: system_SystemIO.cpp:101
GenTree(void)
Definition: GenTree.h:90
GenTree< T, K, C > & operator=(const GenTree< T, K, C > &tree)
Definition: GenTree.h:177
bool isEmpty(void) const
Definition: GenTree.h:105
T2 snd
Definition: Pair.h:19
void set(const T &item)
Definition: GenTree.h:203
bool equals(const GenTree< T, K, C > &tree) const
Definition: GenTree.h:261
T & data(void)
Definition: GenTree.h:132
IntFormat left(IntFormat fmt)
Definition: Output.h:249
Definition: Pair.h:16
int count(void) const
Definition: avl_GenTree.cpp:230
Definition: GenTree.h:54
bool operator!=(const GenTree< T, K, C > &tree) const
Definition: GenTree.h:269
Node * links[2]
Definition: GenTree.h:40
Node(const T &item)
Definition: GenTree.h:59
Node * succ(int dir) const
Definition: GenTree.h:64
Iterator(const GenTree< T, K, C > &tree)
Definition: GenTree.h:116
Definition: GenTree.h:33
void add(const T &item)
Definition: GenTree.h:179
Definition: GenTree.h:114
bool containsAll(const Co< T > &coll) const
Definition: GenTree.h:109
void addAll(const CC &coll)
Definition: GenTree.h:256
bool contains(const typename K::key_t &item) const
Definition: GenTree.h:104