Aleph-w  1.9
General library for algorithms and data structures
tpl_splay_tree.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 /*
28  * Top Dowm Splay Trees
29  */
30 
31 /* This code is a c++ adaptation of Danny Sleator code. It can be loaded from
32 
33  http://www.link.cs.cmu.edu/link/ftp-site/splaying/SplayTree.java
34 
35  */
36 
37 # ifndef TPL_SPLAY_TREE_H
38 # define TPL_SPLAY_TREE_H
39 
40 # include <tpl_binNode.H>
41 # include <tpl_binNodeUtils.H>
42 
43 using namespace Aleph;
44 
45 
46  template <template <class> class NodeType, typename Key, class Compare>
47 class GenTdSplayTree
48 {
49 public:
50 
51  using Node = NodeType<Key>;
52 
53 private:
54 
55  Node headnode;
56  Node * head, *& root;
57  Compare cmp;
58 
59 public:
60 
62  using key_type = Key;
63 
65  Compare & key_comp() noexcept { return cmp; }
66 
68  Compare & get_compare() noexcept { return key_comp(); }
69 
72  void splay(const Key & key) noexcept
73  {
74  Node headNode;
75  Node * l = &headNode;
76  Node * r = &headNode;
77  Node * t = root;
78 
79  while (true)
80  if (cmp(key, KEY(t)))
81  {
82  if (LLINK(t) == Node::NullPtr)
83  break;
84 
85  if (cmp(key, KEY(LLINK(t))))
86  {
87  t = rotate_to_right(t);
88  if (LLINK(t) == Node::NullPtr)
89  break;
90  }
91 
92  LLINK(r) = t;
93  r = t;
94  t = LLINK(t);
95  }
96  else if (cmp(KEY(t), key))
97  {
98  if (RLINK(t) == Node::NullPtr)
99  break;
100 
101  if (cmp(KEY(RLINK(t)), key))
102  {
103  t = rotate_to_left(t);
104  if (RLINK(t) == Node::NullPtr)
105  break;
106  }
107 
108  RLINK(l) = t;
109  l = t;
110  t = RLINK(t);
111  }
112  else
113  break;
114 
115  /* reassembling of sub trees in one with current as root */
116  RLINK(l) = LLINK(t);
117  LLINK(r) = RLINK(t);
118  LLINK(t) = headNode.getR();
119  RLINK(t) = headNode.getL();
120 
121  root = t;
122  }
123 
125  GenTdSplayTree(Compare __cmp = Compare()) noexcept
126  : head(&headnode), root(headnode.getR()), cmp(__cmp)
127  {
128  // Empty
129  }
130 
131  void swap(GenTdSplayTree & tree)
132  {
133  std::swap(root, tree.root);
134  std::swap(cmp, tree.cmp);
135  }
136 
138  virtual ~GenTdSplayTree() { /* empty */ }
139 
140 private:
141 
142  Node * __insert(Node * p) noexcept
143  {
144  if (cmp(KEY(p), KEY(root)))
145  { /* root is predecessor of p */
146  LLINK(p) = LLINK(root);
147  RLINK(p) = root;
148  LLINK(root) = Node::NullPtr;
149  }
150  else
151  { /* root is successor of p */
152  RLINK(p) = RLINK(root);
153  LLINK(p) = root;
154  RLINK(root) = Node::NullPtr;
155  }
156  return root = p; // inserted node become root
157  }
158 
159 public:
160 
167  Node * insert(Node * p) noexcept
168  {
169  assert(p != Node::NullPtr);
170  assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
171 
172  /* test insertion in empty tree */
173  if (root == Node::NullPtr)
174  return root = p;
175 
176  const Key & key = KEY(p);
177 
178  splay(key);
179 
180  if (are_equals<Key, Compare>(KEY(root), key, cmp))
181  return nullptr; // item is already in tree
182 
183  return __insert(p);
184  }
185 
186  Node * insert_dup(Node * p) noexcept
187  {
188  assert(p != Node::NullPtr);
189  assert(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
190 
191  /* test insertion in empty tree */
192  if (root == Node::NullPtr)
193  return root = p;
194 
195  splay(KEY(p));
196 
197  return __insert(p);
198  }
199 
207  Node * search(const Key & key) noexcept
208  {
209  if (root == Node::NullPtr)
210  return nullptr;
211 
212  splay(key);
213 
214  return are_equals<Key, Compare>(KEY(root), key) ? root : nullptr;
215  }
216 
217  Node * search_or_insert(Node * p) noexcept
218  {
219  if (root == Node::NullPtr)
220  return root = p;
221 
222  const Key & key = KEY(p);
223  splay(key);
224  if (are_equals<Key, Compare>(key, KEY(root), cmp))
225  return root;
226 
227  return __insert(p);
228  }
229 
239  Node * remove(const Key & key) noexcept
240  {
241  if (root == Node::NullPtr)
242  return nullptr;
243 
244  splay(key);
245 
246  if (no_equals<Key, Compare>(KEY(root), key, cmp))
247  return nullptr; /* key not found */
248 
249  Node * ret_val = root; /* store node to delete */
250 
251  if (LLINK(root) == Node::NullPtr)
252  root = RLINK(root);
253  else
254  {
255  Node * p = RLINK(root);
256  root = LLINK(root);
257  splay(key);
258  RLINK(root) = p;
259  }
260 
261  ret_val->reset();
262 
263  return ret_val;
264  }
265 
267  Node *& getRoot() noexcept
268  {
269  return root;
270  }
271 
272  bool verify() const { return true; }
273 
282  struct Iterator : public BinNodeInfixIterator<Node>
283  {
284  Iterator(GenTdSplayTree & t) : BinNodeInfixIterator<Node>(t.getRoot()) {}
285  };
286 };
287 
288 
289  template <typename Key, class Compare = Aleph::less<Key>>
290 struct Splay_Tree : public GenTdSplayTree<BinNode, Key, Compare>
291 {
292  using Base = GenTdSplayTree<BinNode, Key, Compare>;
293  using Base::Base;
294 };
295 
296 
297  template <typename Key, class Compare = Aleph::less<Key>>
298 struct Splay_Tree_Vtl : public GenTdSplayTree<BinNodeVtl, Key, Compare>
299 {
300  using Base = GenTdSplayTree<BinNodeVtl, Key, Compare>;
301  using Base::Base;
302 };
303 
304 
305 #endif /* TPL_SPLAY_TREE_H */
Definition: tpl_binNodeUtils.H:2445
Node * rotate_to_right(Node *p) noexcept
Definition: tpl_binNodeUtils.H:1891
Node::Key_Type & KEY(Node *p) noexcept
Definition: tpl_binNode.H:318
Definition: ah-comb.H:35
Node *& LLINK(Node *p) noexcept
Definition: tpl_binNode.H:298
Node * rotate_to_left(Node *p) noexcept
Definition: tpl_binNodeUtils.H:1932
Node *& RLINK(Node *p) noexcept
Definition: tpl_binNode.H:307
Definition: tpl_splay_tree.H:282

Leandro Rabindranath León