Aleph-w  1.9
General library for algorithms and data structures
List.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 /*
29  Aleph implementation of list C++ standard container
30 */
31 
32 # ifndef ALEPH_LIST_H
33 # define ALEPH_LIST_H
34 
35 # include <ah_stdc++_utils.H>
36 # include <tpl_sort_utils.H>
37 
38 namespace Aleph
39 {
40 
48  template <class T>
49 class list
50 {
51  mutable Dnode<T> dlist;
52 
53  typedef Dnode<T> Node;
54 
55 public:
56 
58  typedef T value_type;
59 
61  typedef typename list::value_type & reference;
62 
64  typedef const typename list::value_type & const_reference;
65 
67  typedef size_t size_type;
68 
69 private:
70 
71  mutable size_type num_elem;
72 
73  mutable bool num_elem_is_updated;
74 
75  void reset_num_elem(const size_type & num = 0)
76  {
77  num_elem = num;
78  num_elem_is_updated = true;
79  }
80 
81  void update_num_elem()
82  {
83  assert(not num_elem_is_updated);
84 
85  size_type counter = 0;
86 
87  for (typename Dnode<T>::Iterator it(dlist); it.has_curr(); it.next_ne())
88  ++counter;
89 
90  num_elem = counter;
91  num_elem_is_updated = true;
92  }
93 
94 public:
95 
101  class iterator
102  {
103  friend class list<T>;
104 
105  typedef typename Dnode<T>::Iterator Iterator;
106 
107  Iterator itor;
108 
109  bool underflow;
110  bool overflow;
111 
112  void init_flags()
113  {
114  if (itor.has_curr())
115  underflow = overflow = false;
116  else
117  underflow = overflow = true;
118  }
119 
120  iterator(Dnode<T> & __list) : itor(__list)
121  {
122  init_flags();
123  }
124 
125  void goto_begin()
126  {
127  itor.reset_first();
128  init_flags();
129  }
130 
131  void goto_last()
132  {
133  itor.reset_last();
134  init_flags();
135  }
136 
137  void goto_end()
138  {
139  itor.reset_last();
140  init_flags();
141  if (not overflow)
142  itor.next();
143  overflow = true;
144  }
145 
146  void forward()
147  {
148  if (underflow)
149  {
150  goto_begin();
151  return;
152  }
153 
154  itor.next();
155 
156  if (not itor.has_curr())
157  overflow = true;
158  }
159 
160  void backward()
161  {
162  if (overflow)
163  {
164  goto_last();
165  return;
166  }
167 
168  itor.prev();
169 
170  if (not itor.has_curr())
171  underflow = true;
172  }
173 
174  public:
175 
177  typedef typename list::value_type value_type;
178 
181  typedef int difference_type;
182 
184  typedef typename list::value_type * pointer;
185 
187  typedef typename list::reference reference;
188 
190  iterator() : underflow(false), overflow(false) { /* empty */ }
191 
194  {
195  return itor.get_curr()->get_data();
196  }
197 
200  {
201  return & itor.get_curr()->get_data();
202  }
203 
207  {
208  forward();
209  return *this;
210  }
211 
215  {
216  iterator return_value = *this;
217  forward();
218  return return_value;
219  }
220 
224  {
225  backward();
226  return *this;
227  }
228 
232  {
233  iterator return_value = *this;
234  backward();
235  return return_value;
236  }
237 
239  iterator operator += (const size_type & n)
240  {
241  for (int i = 0; i < n; ++i)
242  forward();
243 
244  return *this;
245  }
246 
248  iterator operator -= (const size_type & n)
249  {
250  for (int i = 0; i < n; ++i)
251  backward();
252 
253  return *this;
254  }
255 
257  bool operator == (const iterator & __itor)
258  {
259  return itor == __itor.itor;
260  }
261 
263  bool operator != (const iterator& __itor)
264  {
265  return itor != __itor.itor;
266  }
267 
268  bool verify (const list<T> & list) const
269  {
270  return itor.verify((Dlink*)(&list.dlist));
271  }
272 
273  bool verify(const iterator & it) const
274  {
275  return itor.verify(it.itor);
276  }
277  }; // end class iterator
278 
279 private:
280 
281  void copy(const list& _list)
282  {
283  assert(dlist.is_empty());
284  assert(num_elem == 0);
285 
286  for (typename Dnode<T>::Iterator it(_list.dlist);
287  it.has_curr(); it.next_ne())
288  {
289  Node * node = new Node(it.get_curr_ne()->get_data());
290 
291  dlist.append(node);
292  ++num_elem;
293  }
294  }
295 
296 public:
297 
299  list() : num_elem(0), num_elem_is_updated(true) { /* empty */ }
300 
302  list(const list & c) : num_elem(0), num_elem_is_updated(true)
303  {
304  copy(c);
305  }
306 
309  list(const size_type & num) : num_elem(0), num_elem_is_updated(true)
310  {
311  for (/* nothing */; num_elem < num; ++num_elem)
312  dlist.append(new Node);
313  }
314 
326  list(const size_type & num, const T & value)
327  : num_elem(0), num_elem_is_updated(true)
328  {
329  for (/* nothing */; num_elem < num; ++num_elem)
330  dlist.append(new Node(value));
331  }
332 
347  template <class Itor>
348  list(Itor beg, const Itor & end)
349  : num_elem(0), num_elem_is_updated(true)
350  {
351  Aleph::verify_iterators(beg, end);
352 
353  while (beg != end)
354  {
355  dlist.append(new Node(*beg++));
356  ++num_elem;
357  }
358  }
359 
360  ~list()
361  {
362  clear();
363  }
364 
366  size_type size()
367  {
368  if (not num_elem_is_updated)
369  update_num_elem();
370 
371  return num_elem;
372  }
373 
375  bool empty() const
376  {
377  return dlist.is_empty();
378  }
379 
382  bool operator == (const list & c) const
383  {
384  if (this == &c)
385  return true;
386 
387  if (num_elem_is_updated and c.num_elem_is_updated)
388  if (num_elem != c.num_elem)
389  return false;
390 
391  typename Dnode<T>::Iterator it_l(*this), it_r(c.dlist);
392 
393  while (it_l.has_curr() and it_r.has_curr())
394  {
395  if (it_l.get_curr_ne()->get_data() != it_r.get_curr_ne()->get_data())
396  return false;
397 
398  it_l.next_ne();
399  it_r.next_ne();
400  }
401 
402  if (it_l.is_empty() and it_r.is_empty())
403  return true;
404 
405  return false;
406  }
407 
410  bool operator != (const list & c) const
411  {
412  return not (*this == c);
413  }
414 
417  bool operator < (const list & c) const
418  {
419  if (this == &c)
420  return false;
421 
422  typename Dnode<T>::Iterator it_l(*this);
423  typename Dnode<T>::Iterator it_r(c);
424 
425  while (it_l.has_curr() and it_r.has_curr())
426  {
427  if (it_l.get_curr_ne()->get_data() < it_r.get_curr_ne()->get_data())
428  return true;
429  else if (it_r.get_curr()->get_data() <
430  it_l.get_curr()->get_data())
431  return false; // no son iguales
432 
433  it_l.next_ne();
434  it_r.next_ne();
435  }
436 
437  return it_l.is_empty();
438  }
439 
442  bool operator > (const list & c) const
443  {
444  return c < *this;
445  }
446 
449  bool operator <= (const list & c) const
450  {
451  return not (c > *this );
452  }
453 
456  bool operator >= (const list & c) const
457  {
458  return not (*this < c);
459  }
460 
463  list & operator = (const list & c)
464  {
465  if (this == &c)
466  return *this;
467 
468  clear();
469  copy(c);
470  }
471 
481  void assign(const size_type & num, const T & value)
482  {
483  clear();
484 
485  for (int n = 0; n < num; ++n)
486  push_back(value);
487  }
488 
499  template <typename Itor>
500  void assign (Itor beg, const Itor & end)
501  {
502  Aleph::verify_iterators(beg, end);
503 
504  clear();
505 
506  while (beg != end)
507  push_back(*beg++);
508  }
509 
512  void swap(list & c)
513  {
514  dlist.swap(c.dlist);
515  std::swap(num_elem, c.num_elem);
516  std::swap(num_elem_is_updated, c.num_elem_is_updated);
517  }
518 
520  reference front() const
521  {
522  return dlist.get_next()->get_data();
523  }
524 
526  reference back() const
527  {
528  return dlist.get_prev()->get_data();
529  }
530 
533  iterator begin() const
534  {
535  return iterator(dlist);
536  }
537 
540  iterator end() const
541  {
542  iterator _itor(dlist);
543  _itor.goto_end();
544 
545  return _itor;
546  }
547 
551  iterator insert(const iterator & pos, const T & value)
552  {
553  Aleph::verify_container_and_iterator(*this, pos);
554 
555  Node * new_node = new Node(value);
556 
557  Node * current_node = pos.itor.get_curr();
558 
559  current_node->append(new_node);
560 
561  pos.itor.set(new_node);
562 
563  ++num_elem;
564 
565  return pos;
566  }
567 
570  void insert(iterator pos, const size_type & num, const T & value)
571  {
572  Aleph::verify_container_and_iterator(*this, pos);
573 
574  Node new_list;
575 
576  try
577  {
578  for (int i = 0; i < num; ++i)
579  new_list.append (new Node(value));
580 
581  Node * current_node = pos.itor.get_curr();
582  current_node->insert_list(&new_list);
583  num_elem += num;
584  }
585  catch (...)
586  {
587  new_list.remove_all_and_delete();
588  throw;
589  }
590  }
591 
594  template <class Itor>
595  void insert(iterator pos, Itor beg, const Itor & end)
596  {
597  Aleph::verify_container_and_iterator(*this, pos);
598  Aleph::verify_iterators(beg, end);
599 
600  Node new_list;
601  try
602  {
603  while (beg != end)
604  {
605  new_list.append(new Node(*beg++));
606  ++num_elem;
607  }
608 
609  Node * current_node = pos.itor.get_curr();
610  current_node->insert_list(&new_list);
611  }
612  catch (...)
613  {
614  new_list.remove_all_and_delete();
615  throw;
616  }
617  }
618 
620  void push_front(const T & value)
621  {
622  dlist.insert(new Node(value));
623  ++num_elem;
624  }
625 
626  void push_back(const T & value)
627  {
628  dlist.append(new Node(value));
629  ++num_elem;
630  }
631 
633  void remove(const T & value)
634  {
635  for (typename Dnode<T>::Iterator it(dlist); it.has_curr(); /* nothing */)
636  if (it.get_curr_ne()->get_data() == value)
637  {
638  delete it.del();
639  --num_elem;
640  }
641  else
642  it.next_ne();
643  }
644 
647  {
648  Aleph::verify_container_and_iterator(*this, pos);
649 
650  delete pos.itor.del();
651  --num_elem;
652 
653  return pos;
654  }
655 
660  {
661  Aleph::verify_container_and_iterator(*this, beg);
662  Aleph::verify_iterators(beg, end);
663 
664  while (beg != end)
665  {
666  delete beg.itor.del();
667  --num_elem;
668  }
669 
670  return beg;
671  }
672 
674  void pop_front()
675  {
676  delete dlist.remove_next();
677  num_elem--;
678  }
679 
681  void pop_back()
682  {
683  delete dlist.remove_prev();
684  --num_elem;
685  }
686 
688  void clear()
689  {
690  dlist.remove_all_and_delete();
691  reset_num_elem();
692  }
693 
712  void resize(size_type num, const T & t = T())
713  {
714  if (num == size())
715  return;
716 
717  if (num < num_elem)
718  {
719  while (num_elem > num)
720  {
721  delete dlist.remove_prev();
722  --num_elem;
723  }
724 
725  return;
726  }
727 
728  iterator itor(end());
729  --itor;
730  insert(itor, num - num_elem, t);
731  }
732 
735  template <class Op>
736  void unique(const Op & op)
737  {
738  reset_num_elem(); // recordar que coloca num_elem = 0
739 
740  for (typename Dnode<T>::Iterator it1(dlist); it1.has_curr();
741  it1.next_ne(), ++num_elem)
742  {
743  typename Dnode<T>::Iterator it2(it1); it2.next_ne();
744 
745  while (it2.has_curr())
746  if (op(it1.get_curr_ne()->get_data(), it2.get_curr_ne()->get_data()))
747  delete it2.del();
748  else
749  break;
750  }
751  }
752 
754  void unique()
755  {
756  unique(Aleph::equal_to<T>());
757  }
758 
771  void splice(iterator pos, list & l)
772  {
773  Aleph::verify_container_and_iterator(*this, pos);
774 
775  pos.itor.get_curr()->insert_list(&l.dlist);
776 
777  num_elem_is_updated = l.num_elem_is_updated;
778  num_elem += l.num_elem;
779 
780  l.reset_num_elem();
781 
782  assert(l.dlist.is_empty());
783  }
784 
798  void splice(iterator pos, list & src_list, iterator src_pos)
799  {
800  Aleph::verify_container_and_iterator(*this, pos);
801  Aleph::verify_container_and_iterator(src_list, src_pos);
802 
803  pos.itor.get_curr()->insert(src_pos.itor.del());
804  --src_list.num_elem;
805  ++num_elem;
806  }
807 
810  void splice(iterator pos, list & src_list,
811  iterator src_beg, const iterator & src_end)
812  {
813  Aleph::verify_container_and_iterator(*this, pos);
814  Aleph::verify_container_and_iterator(src_list, src_beg);
815  Aleph::verify_iterators(src_beg, src_end);
816 
817  Dlink list_to_insert;
818  src_list.dlist.cut_list(src_beg.itor.get_curr(), &list_to_insert);
819 
820  Dlink remaining_list;
821  list_to_insert.cut_list(src_end.itor.get_curr(), &remaining_list);
822 
823  pos.itor.get_curr()->insert_list(&list_to_insert);
824  num_elem_is_updated = false;
825 
826  src_list.dlist.concat_list(&remaining_list);
827  src_list.num_elem_is_updated = false;
828  }
829 
831  template <class Cmp>
832  void sort(const Cmp &)
833  {
834  quicksort<T, Cmp>(dlist);
835  }
836 
838  void sort()
839  {
840  sort(Aleph::less<T>());
841  }
842 
844  template <class Cmp>
845  void merge(list & l, const Cmp &)
846  {
847  Dnode<T> result;
848 
849  Aleph::merge_lists<T, Cmp>(dlist, l.dlist, result);
850 
851  dlist.swap(result);
852 
853  num_elem += l.num_elem;
854 
855  l.reset_num_elem();
856 
857  assert(l.dlist.is_empty());
858  }
859 
861  void merge(list & l)
862  {
863  merge(l, Aleph::less<T>());
864  }
865 
867  void reverse()
868  {
869  reset_num_elem(dlist.reverse_list());
870  }
871 };
872 
873 
874  template <typename T>
875 typename list<T>::size_type distance(typename list<T>::iterator it1,
876  typename list<T>::iterator it2)
877 {
878  typename list<T>::size_type counter = 0;
879 
880  while (it1 != it2)
881  {
882  counter++;
883  it1++;
884  }
885 
886  return counter;
887 }
888 
889 } // end namespace Aleph
890 
891 # endif // ALEPH_LIST_H
void merge(list &l)
Mezcla dos listas ordenadas.
Definition: List.H:861
bool operator==(const iterator &__itor)
Retorna true si los iteradores son iguales.
Definition: List.H:257
Definition: List.H:101
T & operator*()
Proporciona una referencia al elemento actual de iterador.
Definition: List.H:193
Dnode & swap(Dnode &p) noexcept(noexcept(std::swap(data, p.data)))
Swap this with p
Definition: tpl_dnode.H:136
size_type size()
Retorna la cantidad de elementos que tiene la lista.
Definition: List.H:366
list(const size_type &num)
Definition: List.H:309
const list::value_type & const_reference
Tipo referencia constante a elemento dentro de la lista.
Definition: List.H:64
list::value_type & reference
Tipo referencia a elemento dentro de la lista.
Definition: List.H:61
void pop_back()
Elimina de la lista el último elemento.
Definition: List.H:681
void reverse()
Invierte la lista.
Definition: List.H:867
void push_front(const T &value)
Inserta al principio de la lista el valor value.
Definition: List.H:620
reference back() const
Retorna una referencia al último elemento de la lista.
Definition: List.H:526
T value_type
El tipo de dato que maneja la lista.
Definition: List.H:58
list::value_type * pointer
Tipo puntero a elemento dentro de la lista.
Definition: List.H:184
iterator begin() const
Definition: List.H:533
void swap(list &c)
Definition: List.H:512
size_t size_type
Tipo numérico para el tamaño de la lista.
Definition: List.H:67
void splice(iterator pos, list &l)
Definition: List.H:771
bool empty() const
Retorna true si la lista está vacía.
Definition: List.H:375
list(const list &c)
Instancia una lista copia de c.
Definition: List.H:302
T * operator->()
Dereferencia el elemento actual del iterador.
Definition: List.H:199
void merge(list &l, const Cmp &)
Mezcla dos listas ordenadas según criterio de comparación Cmp.
Definition: List.H:845
Dnode< T > * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
Definition: tpl_dnode.H:221
Dnode< T > *& get_next() const noexcept
Return the next node to this
Definition: tpl_dnode.H:53
list & operator=(const list &c)
Definition: List.H:463
iterator operator--()
Definition: List.H:223
bool operator<=(const list &c) const
Definition: List.H:449
reference front() const
Retorna una referencia al primer elemento de la lista.
Definition: List.H:520
bool operator!=(const iterator &__itor)
Retorna true si los iteradores son distintos.
Definition: List.H:263
list()
Instancia una lista vacía.
Definition: List.H:299
bool operator>(const list &c) const
Definition: List.H:442
bool operator<(const list &c) const
Definition: List.H:417
Definition: ah-comb.H:35
iterator operator+=(const size_type &n)
Avanza el iterador n posiciones.
Definition: List.H:239
Dnode< T > * remove_prev() noexcept
Remove the previous node to this; return its address.
Definition: tpl_dnode.H:59
iterator operator++()
Definition: List.H:206
Dnode< T > *& get_prev() const noexcept
Return the previous node to this
Definition: tpl_dnode.H:56
list::value_type value_type
Tipo de dato que almacena lista.
Definition: List.H:177
list::reference reference
Tipo referencia a elemento dentro de la lista.
Definition: List.H:187
void unique(const Op &op)
Definition: List.H:736
void unique()
Elimina de la lista todos los elementos duplicados consecutivos.
Definition: List.H:754
void sort()
Ordena la lista.
Definition: List.H:838
Dnode< T > * remove_next() noexcept
Remove the next node to this; return its address.
Definition: tpl_dnode.H:62
Dnode< T > * get_curr() const
Definition: tpl_dnode.H:231
Dnode * del()
Definition: tpl_dnode.H:244
void splice(iterator pos, list &src_list, iterator src_pos)
Definition: List.H:798
Definition: tpl_dnode.H:206
void assign(Itor beg, const Itor &end)
Definition: List.H:500
iterator end() const
Definition: List.H:540
iterator erase(iterator beg, const iterator &end)
Definition: List.H:659
iterator operator-=(const size_type &n)
Retrocede el iterador n posiciones.
Definition: List.H:248
void sort(const Cmp &)
Ordena la lista según criterio de comparación Cmp.
Definition: List.H:832
void insert(iterator pos, const size_type &num, const T &value)
Definition: List.H:570
int difference_type
Definition: List.H:181
iterator insert(const iterator &pos, const T &value)
Definition: List.H:551
bool operator>=(const list &c) const
Definition: List.H:456
void resize(size_type num, const T &t=T())
Definition: List.H:712
void insert(iterator pos, Itor beg, const Itor &end)
Definition: List.H:595
list(Itor beg, const Itor &end)
Definition: List.H:348
void splice(iterator pos, list &src_list, iterator src_beg, const iterator &src_end)
Definition: List.H:810
void pop_front()
Elimina de la lista el primer elemento.
Definition: List.H:674
Definition: List.H:49
iterator erase(iterator pos)
Elimina el elemento posicionado por el iterador pos.
Definition: List.H:646
void assign(const size_type &num, const T &value)
Definition: List.H:481
list(const size_type &num, const T &value)
Definition: List.H:326
iterator()
Instancia un iterador vacío (no asociado a una lista).
Definition: List.H:190
void clear()
Elimina todos los elementos de la lista.
Definition: List.H:688
Definition: dlink.H:37

Leandro Rabindranath León