cheshirekow  v0.1.0
tree.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Josh Bialkowski (jbialk@mit.edu)
3  *
4  * This file is part of mpblocks.
5  *
6  * mpblocks is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * mpblocks is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with mpblocks. If not, see <http://www.gnu.org/licenses/>.
18  */
25 #ifndef MPBLOCKS_RED_BLACK_TREE_H_
26 #define MPBLOCKS_RED_BLACK_TREE_H_
27 
30 
31 namespace mpblocks {
32 namespace redblack {
33 
35 template <class Traits>
36 class Tree {
37  public:
38  typedef typename Traits::NodeRef NodeRef;
39  typedef typename Traits::NodeOps NodeOps;
40  typedef typename Traits::Key Key;
41 
42  static const Color RED = Color::RED;
43  static const Color BLACK = Color::BLACK;
44 
45  private:
48 
49  size_t m_size;
51 
52  Color& color(NodeRef N){ return m_ops. color(N); }
53  NodeRef& p(NodeRef N){ return m_ops.parent(N); }
54  NodeRef& left(NodeRef N){ return m_ops. left(N); }
55  NodeRef& right(NodeRef N){ return m_ops. right(N); }
56 
57  void swapKey(NodeRef a, NodeRef b) { m_ops.swapKey(a, b); }
58 
59  public:
60  Tree(NodeRef Nil) : Nil(Nil), root(Nil), m_size(0) {}
61 
62  void clear() {
63  root = Nil;
64  m_size = 0;
65  }
66 
67  auto key(NodeRef N) -> decltype(m_ops.key(N)) { return m_ops.key(N); }
68 
70  NodeRef y = right(x); //< set y
71  right(x) = left(y); //< turn y's left subtree into x's right
72  // subtree
73  p(left(y)) = x;
74  p(y) = p(x);
75 
76  if (p(x) == Nil)
77  root = y;
78  else if (x == left(p(x)))
79  left(p(x)) = y;
80  else
81  right(p(x)) = y;
82 
83  left(y) = x; //< put x on y's left
84  p(x) = y;
85  }
86 
88  NodeRef y = left(x); //< set y
89  left(x) = right(y); //< turn y's left subtree into x's left
90  // subtree
91  p(right(y)) = x;
92  p(y) = p(x);
93 
94  if (p(x) == Nil)
95  root = y;
96  else if (x == right(p(x)))
97  right(p(x)) = y;
98  else
99  left(p(x)) = y;
100 
101  right(y) = x; //< put x on y's right
102  p(x) = y;
103  }
104 
106  while (color(p(z)) == RED) {
107  if (p(z) == left(p(p(z)))) {
108  NodeRef y = right(p(p(z)));
109  if (color(y) == RED) {
110  color(p(z)) = BLACK;
111  color(y) = BLACK;
112  color(p(p(z))) = RED;
113  z = p(p(z));
114  } else {
115  if (z == right(p(z))) {
116  z = p(z);
117  leftRotate(z);
118  }
119  color(p(z)) = BLACK;
120  color(p(p(z))) = RED;
121  rightRotate(p(p(z)));
122  }
123  } else {
124  NodeRef y = left(p(p(z)));
125  if (color(y) == RED) {
126  color(p(z)) = BLACK;
127  color(y) = BLACK;
128  color(p(p(z))) = RED;
129  z = p(p(z));
130  } else {
131  if (z == left(p(z))) {
132  z = p(z);
133  rightRotate(z);
134  }
135  color(p(z)) = BLACK;
136  color(p(p(z))) = RED;
137  leftRotate(p(p(z)));
138  }
139  }
140  }
141  color(root) = BLACK;
142  }
143 
144  void insert(NodeRef z) {
145  ++m_size;
146 
147  NodeRef y = Nil;
148  NodeRef x = root;
149  while (x != Nil) {
150  y = x;
151  if (key(z) < key(x))
152  x = left(x);
153  else
154  x = right(x);
155  }
156  p(z) = y;
157  if (y == Nil)
158  root = z;
159  else if (key(z) < key(y))
160  left(y) = z;
161  else
162  right(y) = z;
163 
164  left(z) = Nil;
165  right(z) = Nil;
166  color(z) = RED;
167  insertFixup(z);
168  }
169 
171  while (x != root && color(x) == BLACK) {
172  if (x == left(p(x))) {
173  NodeRef w = right(p(x));
174  if (color(w) == RED) {
175  color(w) = BLACK;
176  color(p(x)) = RED;
177  leftRotate(p(x));
178  w = right(p(x));
179  }
180 
181  if (color(left(w)) == BLACK && color(right(w)) == BLACK) {
182  color(w) = RED;
183  x = p(x);
184  } else {
185  if (color(right(w)) == BLACK) {
186  color(left(w)) = BLACK;
187  color(w) = RED;
188  rightRotate(w);
189  w = right(p(x));
190  }
191  color(w) = color(p(x));
192  color(p(x)) = BLACK;
193  color(right(w)) = BLACK;
194  leftRotate(p(x));
195  x = root;
196  }
197  } else {
198  NodeRef w = left(p(x));
199  if (color(w) == RED) {
200  color(w) = BLACK;
201  color(p(x)) = RED;
202  rightRotate(p(x));
203  w = left(p(x));
204  }
205 
206  if (color(right(w)) == BLACK && color(left(w)) == BLACK) {
207  color(w) = RED;
208  x = p(x);
209  } else {
210  if (color(left(w)) == BLACK) {
211  color(right(w)) = BLACK;
212  color(w) = RED;
213  leftRotate(w);
214  w = left(p(x));
215  }
216  color(w) = color(p(x));
217  color(p(x)) = BLACK;
218  color(left(w)) = BLACK;
219  rightRotate(p(x));
220  x = root;
221  }
222  }
223  }
224  color(x) = BLACK;
225  }
226 
229  while (left(x) != Nil) x = left(x);
230  return x;
231  }
232 
235  while (right(x) != Nil) x = right(x);
236  return x;
237  }
238 
241  if (right(x) != Nil) return treeMinimum(right(x));
242  NodeRef y = p(x);
243  while (y != Nil && x == right(y)) {
244  x = y;
245  y = p(y);
246  }
247  return y;
248  }
249 
252  if (left(x) != Nil) return treeMaximum(left(x));
253  NodeRef y = p(x);
254  while (y != Nil && x == left(y)) {
255  x = y;
256  y = p(y);
257  }
258  return y;
259  }
260 
261  NodeRef remove(NodeRef z) {
262  --m_size;
263 
264  NodeRef x, y;
265 
266  if (left(z) == Nil || right(z) == Nil)
267  y = z;
268  else
269  y = treeSuccessor(z);
270 
271  if (left(y) != Nil)
272  x = left(y);
273  else
274  x = right(y);
275 
276  p(x) = p(y);
277  if (p(y) == Nil)
278  root = x;
279  else if (y == left(p(y)))
280  left(p(y)) = x;
281  else
282  right(p(y)) = x;
283 
284  if (y != z) swapKey(z, y);
285  if (color(y) == BLACK) removeFixup(x);
286  return y;
287  }
288 
290 
292 
293  size_t size() { return m_size; }
294 };
295 
296 } //< namespace redblack
297 } //< namespace mpblocks
298 
299 #endif // MPBLOCKS_RED_BLACK_TREE_H_
void insert(NodeRef z)
Definition: tree.h:144
void insertFixup(NodeRef z)
Definition: tree.h:105
NodeRef treePredecessor(NodeRef x)
CLRS 12.2 page 259.
Definition: tree.h:251
void swapKey(NodeRef a, NodeRef b)
Definition: tree.h:57
void removeFixup(NodeRef x)
Definition: tree.h:170
auto key(NodeRef N) -> decltype(m_ops.key(N))
Definition: tree.h:67
static const Color RED
Definition: tree.h:42
Traits::Key Key
Definition: tree.h:40
NodeRef treeSuccessor(NodeRef x)
CLRS 12.2 page 259.
Definition: tree.h:240
NodeRef treeMinimum(NodeRef x)
CLRS 12.2 page 258.
Definition: tree.h:228
void leftRotate(NodeRef x)
Definition: tree.h:69
NodeRef & p(NodeRef N)
Definition: tree.h:53
Iterator< Traits > begin()
Definition: tree.h:289
NodeRef & left(NodeRef N)
Definition: tree.h:54
Traits::NodeOps NodeOps
Definition: tree.h:39
static const Color BLACK
Definition: tree.h:43
NodeRef treeMaximum(NodeRef x)
CLRS 12.2 page 258.
Definition: tree.h:234
Tree(NodeRef Nil)
Definition: tree.h:60
implements red black trees from CLRS
Definition: iterator.h:38
Traits::NodeRef NodeRef
Definition: tree.h:38
NodeRef & right(NodeRef N)
Definition: tree.h:55
Iterator< Traits > end()
Definition: tree.h:291
void rightRotate(NodeRef x)
Definition: tree.h:87
Color & color(NodeRef N)
Definition: tree.h:52