libwordring
tree.hpp
1 #pragma once
2 
3 #include <algorithm>
4 #include <array>
5 #include <iterator>
6 #include <limits>
7 #include <memory>
8 #include <type_traits>
9 #include <utility>
10 #include <vector>
11 
12 namespace wordring
13 {
14  template <typename T, typename Allocator>
15  class tree;
16 }
17 
18 namespace wordring::detail
19 {
20  // ------------------------------------------------------------------------
21  // tree_node
22  // ------------------------------------------------------------------------
23 
24  template <typename T>
25  struct tree_node
26  {
27  using index_type = std::uint32_t;
28  using value_type = T;
29 
30  static constexpr index_type null_value = 0;
31 
32  index_type m_parent;
33  index_type m_prev;
34  index_type m_next;
35  index_type m_child;
36 
37  value_type m_value;
38  };
39 
40  // ------------------------------------------------------------------------
41  // tree_node_iterator
42  // ------------------------------------------------------------------------
43 
44  template <typename Container>
46  {
47  template <typename T1, typename Allocator1>
48  friend class wordring::tree;
49 
50  template <typename Container1>
51  friend class tree_node_iterator;
52 
53  template <typename Container1, typename Container2>
54  friend bool operator==(tree_node_iterator<Container1> const&, tree_node_iterator<Container2> const&);
55 
56  template <typename Container1, typename Container2>
57  friend bool operator!=(tree_node_iterator<Container1> const&, tree_node_iterator<Container2> const&);
58 
59  protected:
60  using container = Container;
61  using node_type = typename container::value_type;
62  using index_type = typename node_type::index_type;
63 
64  static constexpr index_type null_value = node_type::null_value;
65 
66  public:
67  using value_type = typename node_type::value_type;
68  using difference_type = std::ptrdiff_t;
69  using reference = value_type&;
70  using const_reference = value_type const&;
71  using pointer = value_type*;
72  using const_pointer = value_type const*;
73  using iterator_category = std::bidirectional_iterator_tag;
74 
75  using reverse_iterator = std::reverse_iterator<tree_node_iterator<container>>;
76 
77  public:
80  tree_node_iterator() noexcept
81  : m_c(nullptr)
82  , m_parent(null_value)
83  , m_index(null_value)
84  {
85  }
86 
87  protected:
92  tree_node_iterator(container& c, index_type parent, index_type idx) noexcept
93  : m_c(std::addressof(c))
94  , m_parent(parent)
95  , m_index(idx)
96  {
97  }
98 
99  public:
103  {
105  result.m_c = m_c;
106  result.m_parent = m_parent;
107  result.m_index = m_index;
108  return result;
109  }
110 
113  auto& operator*() const
114  {
115  assert(m_index != null_value);
116 
117  return (m_c->data() + m_index)->m_value;
118  }
119 
122  auto operator->() const
123  {
124  assert(m_index != null_value);
125 
126  return std::addressof((m_c->data() + m_index)->m_value);
127  }
128 
132  {
133  assert(m_index != null_value);
134 
135  m_index = (m_c->data() + m_index)->m_next;
136 
137  return *this;
138  }
139 
143  {
144  assert(m_index != null_value);
145 
146  auto result = *this;
147  operator++();
148 
149  return result;
150  }
151 
152  /* @brief デクリメントする
153  */
154  tree_node_iterator& operator--()
155  {
156  auto const* d = m_c->data();
157 
158  if (m_index != 0) // prevがある場合(end以外はある)
159  {
160  assert(m_parent != 0 && (d + m_parent)->m_child != m_index); // 先頭をデクリメントしようとしている。
161  m_index = (d + m_index)->m_prev;
162  }
163  else if (m_parent != 0) // prevが無い(endは無い)且つ根以外の場合
164  {
165  index_type child = (d + m_parent)->m_child; // begin
166  m_index = (d + child)->m_prev; // endの前はtail
167  }
168  else // 根の終端
169  {
170  m_index = d->m_child;
171  assert(m_index != 0); // 空のツリーで根をデクリメントしようとしている。
172  }
173 
174  return *this;
175  }
176 
177  /* @brief デクリメントする
178  */
179  tree_node_iterator operator--(int)
180  {
181  auto result = *this;
182  operator--();
183  return result;
184  }
185 
189  {
190  assert(m_index != null_value);
191  return tree_node_iterator(*m_c, m_index, (m_c->data() + m_index)->m_child);
192  }
193 
197  {
198  assert(m_index != null_value);
199  return tree_node_iterator(*m_c, m_index, null_value);
200  }
201 
204  reverse_iterator rbegin() const
205  {
206  return std::make_reverse_iterator(end());
207  }
208 
211  reverse_iterator rend() const
212  {
213  return std::make_reverse_iterator(begin());
214  }
215 
223  {
224  auto* d = m_c->data();
225 
226  index_type p = m_parent; // 親
227  index_type pp = (p == null_value) ? null_value : (d + p)->m_parent; // 親の親
228 
229  return tree_node_iterator(*m_c, pp, p);
230  }
231 
232  protected:
233  container* m_c;
234  index_type m_parent;
235  index_type m_index;
236  };
237 
238  template <typename Container1, typename Container2>
239  inline bool operator==(tree_node_iterator<Container1> const& lhs, tree_node_iterator<Container2> const& rhs)
240  {
241  return !(lhs != rhs);
242  }
243 
244  template <typename Container1, typename Container2>
245  inline bool operator!=(tree_node_iterator<Container1> const& lhs, tree_node_iterator<Container2> const& rhs)
246  {
247 #ifndef NDEBUG
248  Container1 const* c1 = const_cast<Container1 const*>(lhs.m_c);
249  Container2 const* c2 = const_cast<Container1 const*>(lhs.m_c);
250  assert(c1 == c2 || c1 == nullptr || c2 == nullptr);
251 #endif
252 
253  return lhs.m_index != rhs.m_index || lhs.m_parent != rhs.m_parent;
254  }
255 }
256 
257 namespace wordring
258 {
259  // ------------------------------------------------------------------------
260  // tree
261  // ------------------------------------------------------------------------
262 
333  template <typename T, typename Allocator = std::allocator<detail::tree_node<T>>>
334  class tree
335  {
336  template <typename Container1>
337  friend class detail::tree_node_iterator;
338 
339  protected:
340  using node_type = detail::tree_node<T>;
341  using index_type = typename node_type::index_type;
342  using container = std::vector<node_type, Allocator>;
343 
344  static constexpr index_type null_value = node_type::null_value;
345 
346  public:
347  // メンバ型
348  using value_type = T;
349  using allocator_type = Allocator;
350  using size_type = std::size_t;
351  using difference_type = std::ptrdiff_t;
352  using reference = value_type&;
353  using const_reference = value_type const&;
354  using pointer = value_type*;
355  using const_pointer = value_type const*;
356  using iterator = detail::tree_node_iterator<container>;
357  using const_iterator = detail::tree_node_iterator<container const>;
358 
359  public:
363  : m_c(1, node_type{})
364  {
365  }
366 
371  explicit tree(allocator_type const& alloc)
372  : m_c(1, node_type{}, alloc)
373  {
374  }
375 
381  explicit tree(value_type const& value, allocator_type const& alloc = allocator_type())
382  : m_c(1, node_type{}, alloc)
383  {
384  insert(begin(), value);
385  }
386 
392  explicit tree(value_type&& value, allocator_type const& alloc = allocator_type())
393  : m_c(1, node_type{}, alloc)
394  {
395  insert(begin(), std::move(value));
396  }
397 
398  void assign(value_type const& value)
399  {
400  clear();
401  insert(begin(), value);
402  }
403 
404  void assign(value_type&& value)
405  {
406  clear();
407  insert(begin(), std::move(value));
408  }
409 
410  allocator_type get_allocator() const { return m_c.get_allocator(); }
411 
412  // 要素アクセス --------------------------------------------------------
413 
414  reference front()
415  {
416  assert(!empty());
417  return *begin();
418  }
419 
420  const_reference front() const
421  {
422  assert(!empty());
423  return *cbegin();
424  }
425 
426  reference back() { return front(); }
427 
428  const_reference back() const { return front(); }
429 
430  // イテレータ ----------------------------------------------------------
431 
436  iterator begin() noexcept { return iterator(m_c, 0, m_c[0].m_child); }
437 
442  const_iterator begin() const noexcept { return const_iterator(m_c, 0, m_c[0].m_child); }
443 
448  const_iterator cbegin() const noexcept { return begin(); }
449 
454  iterator end() noexcept { return iterator(m_c, 0, 0); }
455 
460  const_iterator end() const noexcept { return const_iterator(m_c, 0, 0); }
461 
466  const_iterator cend() const noexcept { return end(); }
467 
468  // 容量 ---------------------------------------------------------------
469 
474  bool empty() const noexcept { return size() == 0; }
475 
480  size_type size() const
481  {
482  size_type n = 0;
483  const_iterator it1 = begin();
484  const_iterator it2 = end();
485 
486  while (it1 != it2)
487  {
488  n += size(it1);
489  ++it1;
490  }
491 
492  return n;
493  }
494 
501  size_type size(const_iterator pos) const
502  {
503  index_type idx = pos.m_index;
504  if (idx == 0) return 0;
505 
506  index_type n = 0;
507 
508  node_type const* d = m_c.data();
509 
510  std::vector<index_type> stack(1, idx);
511  while (!stack.empty())
512  {
513  index_type parent = stack.back();
514  stack.pop_back();
515  ++n;
516 
517  for (index_type i = (d + parent)->m_child; i != 0; i = (d + i)->m_next) stack.push_back(i);
518  }
519 
520  return static_cast<std::make_unsigned_t<index_type>>(n);
521  }
522 
527  size_type max_size() const noexcept { return m_c.max_size(); }
528 
529  // 変更 ---------------------------------------------------------------
530 
533  void clear() noexcept
534  {
535  m_c.clear();
536  m_c.emplace_back(node_type{});
537  }
538 
539  void swap(tree& other) { m_c.swap(other.m_c); }
540 
551  iterator insert(const_iterator pos, value_type&& value)
552  {
553  index_type idx = allocate(std::move(value));
554 
555  link(pos.m_parent, pos.m_index, idx);
556 
557  return iterator(m_c, pos.m_parent, idx);
558  }
559 
569  iterator insert(const_iterator pos, value_type const& value)
570  {
571  return insert(pos, std::move(value_type(value)));
572  }
573 
613  {
614  std::vector<std::array<const_iterator, 2>> x; // 親スタック [pos, sub]
615  std::vector<const_iterator> v; // 探索スタック
616 
617  // 根を特別扱い
618  iterator ret = insert(pos, *sub);
619  x.push_back({ ret, sub });
620  {
621  auto it1 = sub.rbegin();
622  auto it2 = sub.rend();
623  while (it1 != it2) v.push_back((++it1).base());
624  }
625 
626  // 根以外
627  while (!v.empty())
628  {
629  const_iterator it = v.back();
630  v.pop_back();
631 
632  if (it.parent() != x.back()[1]) x.pop_back();
633  const_iterator p = insert(x.back()[0].end(), *it);
634 
635  if (it.begin() != it.end()) // 子がある
636  {
637  auto it1 = it.rbegin();
638  auto it2 = it.rend();
639  while(it1 != it2) v.push_back((++it1).base());
640 
641  x.push_back({ p, it });
642  }
643  }
644 
645  return ret;
646  }
647 
648  template <typename... Args>
649  iterator emplace(const_iterator pos, Args&&... args)
650  {
651  return insert(pos, value_type(std::forward<Args>(args)...));
652  }
653 
673  {
674  node_type* d = m_c.data();
675 
676  for (index_type i = pos.m_index; i != 0; i = (d + i)->m_parent)
677  {
678  if (i == sub.m_index) throw std::invalid_argument("");
679  }
680 
681  unlink(sub.m_index);
682  link(pos.m_parent, pos.m_index, sub.m_index);
683 
684  return iterator(m_c, pos.m_parent, sub.m_index);
685  }
686 
695  {
696  assert(pos.m_index != 0);
697 
698  node_type* d = m_c.data();
699 
700  index_type idx = pos.m_index;
701  index_type parent = pos.m_parent;
702  index_type after = (d + idx)->m_next;
703 
704  unlink(idx);
705 
706  // 解放
707  std::vector<index_type> v(1, idx);
708  while (!v.empty())
709  {
710  index_type i = v.back();
711  v.pop_back();
712  for (index_type j = (d + i)->m_child; j != 0; j = (d + j)->m_next) v.push_back(j); // i の子をスタックに追加
713 
714  free(i);
715  }
716 
717  return iterator(m_c, parent, after);
718  }
719 
720  protected:
721  // 内部 ---------------------------------------------------------------
722 
729  index_type allocate(value_type&& val)
730  {
731  node_type* d = m_c.data();
732  index_type idx = d->m_next;
733 
734  if (idx == 0)
735  {
736  idx = m_c.size();
737  m_c.emplace_back(node_type{ 0, 0, 0, 0, std::move(val) });
738  }
739  else
740  {
741  index_type before = (d + idx)->m_prev;
742  index_type after = (d + idx)->m_next;
743  (d + idx)->m_value = std::move(val);
744 
745  (d + before)->m_next = after;
746  (d + after)->m_prev = before;
747  }
748 
749  return idx;
750  }
751 
756  void free(index_type idx)
757  {
758  assert(idx < m_c.size());
759 
760  node_type* d = m_c.data();
761 
762  // idx を超えない最後の未使用ノードを探す
763  index_type before = 0;
764  for (index_type i = d->m_next; i != 0 && i < idx; i = (d + before)->m_next) before = i;
765 
766  // idx を超える最初の未使用ノードを探す
767  index_type after = (d + before)->m_next;
768 
769  // リンクを張り替える
770  (d + before)->m_next = idx;
771 
772  (d + idx)->m_prev = before;
773  (d + idx)->m_next = after;
774 
775  (d + after)->m_prev = idx;
776 
777  // 使わない項目を0に初期化
778  (d + idx)->m_parent = 0;
779  (d + idx)->m_child = 0;
780  }
781 
907  void link(index_type parent, index_type pos, index_type idx)
908  {
909  node_type* d = m_c.data();
910 
911  index_type child = (d + parent)->m_child;
912  index_type after = pos;
913  index_type before = 0;
914  if (after != 0) before = (child != after) ? (d + after)->m_prev : 0;
915  else before = (child != 0) ? (d + child)->m_prev : 0;
916 
917  if (before == 0)
918  {
919  (d + parent)->m_child = idx;
920  index_type tail = (after != 0) ? (d + after)->m_prev : idx;
921  (d + idx)->m_prev = tail;
922  }
923  else
924  {
925  (d + before)->m_next = idx;
926  (d + idx)->m_prev = before;
927  }
928 
929  if (after == 0)
930  {
931  (d + idx)->m_next = 0;
932  if (before != 0) (d + child)->m_prev = idx;
933  }
934  else
935  {
936  (d + after)->m_prev = idx;
937  (d + idx)->m_next = after;
938  }
939  (d + idx)->m_parent = parent;
940  }
941 
1028  void unlink(index_type idx)
1029  {
1030  assert(idx != 0);
1031 
1032  node_type* d = m_c.data();
1033 
1034  index_type parent = (d + idx)->m_parent;
1035  index_type child = (d + parent)->m_child;
1036  index_type before = (child != idx) ? (d + idx)->m_prev : 0;
1037  index_type after = (d + idx)->m_next;
1038 
1039  if (before == 0)
1040  {
1041  if (after == 0) (d + parent)->m_child = 0;
1042  else
1043  {
1044  (d + parent)->m_child = after;
1045  (d + after)->m_prev = (d + idx)->m_prev;
1046  }
1047  }
1048  else (d + before)->m_next = after;
1049 
1050  if (after == 0)
1051  {
1052  if (before != 0) (d + child)->m_prev = before;
1053  }
1054  else (d + after)->m_prev = (d + idx)->m_prev;
1055  }
1056 
1057  protected:
1058  container m_c;
1059  };
1060 }
wordring::detail::tree_node_iterator::end
tree_node_iterator end() const
子の終端を指すイテレータを取得する
Definition: tree.hpp:196
wordring::detail::tree_node_iterator::tree_node_iterator
tree_node_iterator(container &c, index_type parent, index_type idx) noexcept
イテレータを作成する
Definition: tree.hpp:92
wordring::tree::allocate
index_type allocate(value_type &&val)
ノードを確保する
Definition: tree.hpp:729
wordring::detail::tree_node_iterator::operator*
auto & operator*() const
イテレータが指す要素の参照を取得する
Definition: tree.hpp:113
wordring::detail::tree_node_iterator::parent
tree_node_iterator parent() const
親を指すイテレータを取得する
Definition: tree.hpp:222
wordring::tree::erase
iterator erase(const_iterator pos)
要素を削除する
Definition: tree.hpp:694
wordring::detail::tree_node_iterator::operator->
auto operator->() const
イテレータが指す要素のポインタを取得する
Definition: tree.hpp:122
wordring::tree
木コンテナ
Definition: tree.hpp:15
wordring::tree::cend
const_iterator cend() const noexcept
根の終端を指すイテレータを返す
Definition: tree.hpp:466
wordring::detail::tree_node_iterator::rend
reverse_iterator rend() const
子の先頭の前を指す逆走イテレータを取得する
Definition: tree.hpp:211
wordring::tree::begin
const_iterator begin() const noexcept
根を指すイテレータを返す
Definition: tree.hpp:442
wordring::tree::clear
void clear() noexcept
すべての要素を削除する
Definition: tree.hpp:533
wordring::detail::tree_node_iterator::rbegin
reverse_iterator rbegin() const
子の末尾を指す逆走イテレータを取得する
Definition: tree.hpp:204
wordring::tree::cbegin
const_iterator cbegin() const noexcept
根を指すイテレータを返す
Definition: tree.hpp:448
wordring::tree::tree
tree()
空のコンテナを構築する
Definition: tree.hpp:362
wordring::detail::tree_node_iterator::tree_node_iterator
tree_node_iterator() noexcept
空のイテレータを作成する
Definition: tree.hpp:80
wordring
Definition: algorithm_.hpp:10
wordring::tree::tree
tree(allocator_type const &alloc)
アロケータを指定して空のコンテナを構築する
Definition: tree.hpp:371
wordring::detail::tree_node_iterator::operator++
tree_node_iterator & operator++()
インクリメントする
Definition: tree.hpp:131
wordring::tree::size
size_type size() const
格納している要素数を調べる
Definition: tree.hpp:480
wordring::detail::tree_node_iterator::operator++
tree_node_iterator operator++(int)
インクリメントする
Definition: tree.hpp:142
wordring::tree::size
size_type size(const_iterator pos) const
部分木が格納するノード数を調べる
Definition: tree.hpp:501
wordring::tree::end
iterator end() noexcept
根の終端を指すイテレータを返す
Definition: tree.hpp:454
wordring::detail::tree_node_iterator
Definition: tree.hpp:45
wordring::tree::empty
bool empty() const noexcept
要素を格納していないことを調べる
Definition: tree.hpp:474
wordring::tree::insert
iterator insert(const_iterator pos, const_iterator sub)
部分木を挿入する
Definition: tree.hpp:612
wordring::tree::tree
tree(value_type &&value, allocator_type const &alloc=allocator_type())
要素からコンテナを構築する
Definition: tree.hpp:392
wordring::tree::link
void link(index_type parent, index_type pos, index_type idx)
ノードを木に挿入する
Definition: tree.hpp:907
wordring::tree::end
const_iterator end() const noexcept
根の終端を指すイテレータを返す
Definition: tree.hpp:460
wordring::tree::unlink
void unlink(index_type idx)
ノードを木から取り除く
Definition: tree.hpp:1028
wordring::detail::tree_node_iterator::begin
tree_node_iterator begin() const
子の先頭を指すイテレータを取得する
Definition: tree.hpp:188
wordring::tree::move
iterator move(const_iterator pos, const_iterator sub)
部分木を移動する
Definition: tree.hpp:672
wordring::detail
wordring::detail::tree_node
Definition: tree.hpp:25
wordring::tree::insert
iterator insert(const_iterator pos, value_type &&value)
ノードを挿入する
Definition: tree.hpp:551
wordring::tree::free
void free(index_type idx)
ノードを解放する
Definition: tree.hpp:756
wordring::tree::insert
iterator insert(const_iterator pos, value_type const &value)
要素を挿入する
Definition: tree.hpp:569
wordring::tree::max_size
size_type max_size() const noexcept
格納可能な要素の最大数を調べる
Definition: tree.hpp:527
wordring::tree::tree
tree(value_type const &value, allocator_type const &alloc=allocator_type())
要素からコンテナを構築する
Definition: tree.hpp:381
wordring::tree::begin
iterator begin() noexcept
根を指すイテレータを返す
Definition: tree.hpp:436