39 #ifndef DAL_TREE_SORTED_H__
40 #define DAL_TREE_SORTED_H__
53 static const size_t DEPTHMAX__ = 64;
54 static const size_t ST_NIL = size_t(-1);
56 template<
typename T,
typename COMP = gmm::less<T>,
unsigned char pks = 5>
57 class dynamic_tree_sorted;
59 template<
typename T,
typename COMP,
unsigned char pks>
struct tsa_iterator {
61 typedef value_type& reference;
62 typedef value_type* pointer;
64 typedef ptrdiff_t difference_type;
65 typedef std::bidirectional_iterator_tag iterator_category;
68 dynamic_tree_sorted<T, COMP, pks> *p;
74 tsa_iterator(dynamic_tree_sorted<T, COMP, pks> &tsa)
75 { p = &tsa; depth = 0; }
76 void copy(
const tsa_iterator<T, COMP, pks> &it);
77 tsa_iterator(
const tsa_iterator &it) {
copy(it); }
78 tsa_iterator &operator =(
const tsa_iterator &it)
79 {
copy(it);
return *
this;}
82 {
return (depth==0) ? ST_NIL : path[depth-1];}
84 {
return (depth<=1) ? ST_NIL : path[depth-2];}
86 {
return path[(depth-1) & 63]; }
88 {
return (depth==0) ? 0 : dir[depth-1];}
89 inline void up(
void) {
if (depth > 0) depth--; }
91 void down_right(
void);
92 void down_left_all(
void);
93 void down_right_all(
void);
94 void root(
void) { path[0] = p->root_elt(); dir[0] = 0; depth = 1; }
95 void first(
void) { root(); down_left_all(); }
96 void last(
void) { root(); down_right_all(); }
97 void end(
void) { depth = 0; }
99 tsa_iterator &operator ++();
100 tsa_iterator &operator --();
101 tsa_iterator operator ++(
int)
102 { tsa_iterator tmp = *
this; ++(*this);
return tmp; }
103 tsa_iterator operator --(
int)
104 { tsa_iterator tmp = *
this; --(*this);
return tmp; }
106 reference operator *()
const {
return (*p)[index()]; }
107 pointer operator->()
const {
return &(operator*()); }
109 bool operator ==(
const tsa_iterator &i)
const
110 {
return ((i.depth == 0 && depth == 0) || (i.index_() == index_())); }
111 bool operator !=(
const tsa_iterator &i)
const
112 {
return !((i.depth == 0 && depth == 0) || (i.index_() == index_())); }
115 template<
typename T,
typename COMP,
unsigned char pks>
116 void tsa_iterator<T, COMP, pks>::copy(
const tsa_iterator<T, COMP, pks> &it) {
117 p = it.p; depth = it.depth;
118 size_type *p1it=&(path[0]), *pend=&path[depth];
122 while (p1it != pend) { *p1it++ = *p2it++; *d1it++ = *d2it++; }
125 template<
typename T,
typename COMP,
unsigned char pks>
126 void tsa_iterator<T, COMP, pks>::down_left(
void) {
127 GMM_ASSERT3(depth > 0 && depth < DEPTHMAX__ && index() != ST_NIL,
129 path[depth] = p->left_elt(index_()); dir[depth++] = -1;
132 template<
typename T,
typename COMP,
unsigned char pks>
133 void tsa_iterator<T, COMP, pks>::down_right(
void) {
134 GMM_ASSERT3(depth > 0 && depth < DEPTHMAX__ && index() != ST_NIL,
136 path[depth] = p->right_elt(index_()); dir[depth++] = 1;
139 template<
typename T,
typename COMP,
unsigned char pks>
140 void tsa_iterator<T, COMP, pks>::down_left_all(
void)
141 {
while (index_() != ST_NIL) down_left(); up(); }
143 template<
typename T,
typename COMP,
unsigned char pks>
144 void tsa_iterator<T, COMP, pks>::down_right_all(
void)
145 {
while (index_() != ST_NIL) down_right(); up();}
147 template<
typename T,
typename COMP,
unsigned char pks>
148 tsa_iterator<T, COMP, pks> &tsa_iterator<T, COMP, pks>::operator ++() {
149 if (depth == 0) first();
150 if (p->right_elt(index_()) != ST_NIL) { down_right(); down_left_all(); }
151 else { up();
while (dir[depth] == 1) up(); }
155 template<
typename T,
typename COMP,
unsigned char pks>
156 tsa_iterator<T, COMP, pks> &tsa_iterator<T, COMP, pks>::operator --() {
157 if (depth == 0) last();
158 if (p->left_elt(index_()) != ST_NIL) { down_left(); down_right_all(); }
159 else { up();
while (dir[depth] == -1) up(); }
164 template<
typename T,
typename COMP,
unsigned char pks>
struct const_tsa_iterator {
165 typedef T value_type;
166 typedef const value_type& reference;
167 typedef const value_type* pointer;
169 typedef ptrdiff_t difference_type;
170 typedef std::bidirectional_iterator_tag iterator_category;
173 const dynamic_tree_sorted<T, COMP, pks> *p;
178 const_tsa_iterator(
void) {}
179 const_tsa_iterator(
const dynamic_tree_sorted<T, COMP, pks> &tsa)
180 { p = &tsa; depth = 0; }
181 void copy(
const const_tsa_iterator<T, COMP, pks> &it);
182 const_tsa_iterator(
const const_tsa_iterator &it) { this->
copy(it); }
183 const_tsa_iterator(
const tsa_iterator<T, COMP, pks> &it);
184 const_tsa_iterator &operator =(
const const_tsa_iterator &it)
185 {
copy(it);
return *
this; }
188 {
return (depth==0) ? ST_NIL : path[depth-1];}
190 {
return (depth<=1) ? ST_NIL : path[depth-2];}
191 inline size_type index_(
void)
const {
return path[depth-1]; }
193 {
return (depth==0) ?
short_type(0) : dir[depth-1];}
194 inline void up(
void) {
if (depth > 0) depth--; }
195 void down_left(
void);
196 void down_right(
void);
197 void down_left_all(
void);
198 void down_right_all(
void);
199 void root(
void) { path[0] = p->root_elt(); dir[0] = 0; depth = 1; }
200 void first(
void) { root(); down_left_all(); }
201 void last(
void) { root(); down_right_all(); }
202 void end(
void) { depth = 0; }
204 const_tsa_iterator &operator ++();
205 const_tsa_iterator &operator --();
206 const_tsa_iterator operator ++(
int)
207 { const_tsa_iterator tmp = *
this; ++(*this);
return tmp; }
208 const_tsa_iterator operator --(
int)
209 { const_tsa_iterator tmp = *
this; --(*this);
return tmp; }
211 reference operator *()
const {
return (*p)[index()]; }
212 pointer operator->()
const {
return &(operator*()); }
214 bool operator ==(
const const_tsa_iterator &i)
const
215 {
return ((i.depth == 0 && depth == 0) || (i.index_() == index_())); }
216 bool operator !=(
const const_tsa_iterator &i)
const
217 {
return !((i.depth == 0 && depth == 0) || (i.index_() == index_())); }
220 template<
typename T,
typename COMP,
unsigned char pks>
222 const const_tsa_iterator<T,COMP,pks>& it) {
223 o <<
"const_tsa_iterator : depth=" << it.depth <<
", path/dir=[";
224 for (
unsigned i=0; i < it.depth; ++i)
225 o <<
"{" << it.path[i] <<
", " <<
int(it.dir[i]) <<
"} ";
230 template<
typename T,
typename COMP,
unsigned char pks>
231 void const_tsa_iterator<T, COMP, pks>::copy
232 (
const const_tsa_iterator<T, COMP, pks> &it) {
233 p = it.p; depth = it.depth;
234 size_type *p1it=&(path[0]), *pend=&path[depth];
238 while (p1it != pend) { *p1it++ = *p2it++; *d1it++ = *d2it++; }
241 template<
typename T,
typename COMP,
unsigned char pks>
242 const_tsa_iterator<T, COMP, pks>::const_tsa_iterator
243 (
const tsa_iterator<T, COMP, pks> &it) {
244 p = it.p; depth = it.depth;
245 size_type *p1it=&(path[0]), *pend=&path[depth];
249 while (p1it != pend) { *p1it++ = *p2it++; *d1it++ = *d2it++; }
252 template<
typename T,
typename COMP,
unsigned char pks>
253 void const_tsa_iterator<T, COMP, pks>::down_left(
void) {
254 GMM_ASSERT3(depth > 0 && depth < DEPTHMAX__ && index() != ST_NIL,
256 path[depth] = p->left_elt(index_()); dir[depth++] = -1;
259 template<
typename T,
typename COMP,
unsigned char pks>
260 void const_tsa_iterator<T, COMP, pks>::down_right(
void) {
261 GMM_ASSERT3(depth > 0 && depth < DEPTHMAX__ && index() != ST_NIL,
263 path[depth] = p->right_elt(index_()); dir[depth++] = 1;
266 template<
typename T,
typename COMP,
unsigned char pks>
267 void const_tsa_iterator<T, COMP, pks>::down_left_all(
void)
268 {
while (index_() != ST_NIL) down_left(); up(); }
270 template<
typename T,
typename COMP,
unsigned char pks>
271 void const_tsa_iterator<T, COMP, pks>::down_right_all(
void)
272 {
while (index_() != ST_NIL) down_right(); up();}
274 template<
typename T,
typename COMP,
unsigned char pks>
275 const_tsa_iterator<T, COMP, pks> &
276 const_tsa_iterator<T, COMP, pks>::operator ++() {
277 if (depth == 0) last();
278 if (p->right_elt(index_()) != ST_NIL) { down_right(); down_left_all(); }
279 else { up();
while (dir[depth] == 1) up(); }
283 template<
typename T,
typename COMP,
unsigned char pks>
284 const_tsa_iterator<T, COMP, pks> &
285 const_tsa_iterator<T, COMP, pks>::operator --() {
286 if (depth == 0) last();
287 if (p->left_elt(index_()) != ST_NIL) { down_left(); down_right_all(); }
288 else { up();
while (dir[depth] == -1) up(); }
296 template<
typename T,
typename COMP,
unsigned char pks>
297 class dynamic_tree_sorted :
public dynamic_tas<T, pks> {
300 typedef typename dynamic_tas<T, pks>::tas_iterator tas_iterator;
301 typedef typename dynamic_tas<T, pks>::const_tas_iterator const_tas_iterator;
302 typedef typename dynamic_tas<T, pks>::iterator iterator;
303 typedef typename dynamic_tas<T, pks>::const_iterator const_iterator;
307 typedef tsa_iterator<T, COMP, pks> sorted_iterator;
308 typedef const_tsa_iterator<T, COMP, pks> const_sorted_iterator;
309 typedef std::reverse_iterator<const_iterator> const_reverse_sorted_iterator;
310 typedef std::reverse_iterator<iterator> reverse_sorted_iterator;
318 inline void init(
void) { eq = 0; r = l = ST_NIL; }
319 tree_elt(
void) { init(); }
322 dynamic_array<tree_elt, pks> nodes;
331 void add_index(
size_type i, const_sorted_iterator &it);
332 void sup_index(
size_type i, const_sorted_iterator &it);
338 if (i == ST_NIL)
return 0;
339 int l = verify_balance(nodes[i].l);
340 int r = verify_balance(nodes[i].r);
341 GMM_ASSERT3(
short_type(r - l) == nodes[i].eq &&
342 (nodes[i].eq <= 1 && nodes[i].eq>=-1),
"internal error");
343 return std::max(l,r) + 1;
346 void insert_path(
const T &elt, const_sorted_iterator &it)
const;
347 void search_sorted_iterator(
const T &elt,
348 const_sorted_iterator &it)
const;
349 void find_sorted_iterator(
size_type i, const_sorted_iterator &it)
const;
350 COMP &comparator(
void) {
return compar; }
351 const COMP &comparator(
void)
const {
return compar; }
353 dynamic_tree_sorted(COMP cp = COMP())
354 { first_node = ST_NIL; compar = cp; }
356 size_type root_elt(
void)
const {
return first_node; }
360 {
return short_type((n == ST_NIL) ? 0 : nodes[n].eq); }
362 const_sorted_iterator it(*
this);
363 search_sorted_iterator(elt,it);
369 { first_node = ST_NIL; nodes.clear(); dynamic_tas<T,pks>::clear(); }
372 size_type add_norepeat(
const T &,
bool replace =
false,
373 bool *present = NULL);
379 sorted_iterator sorted_begin(
void)
380 { sorted_iterator it(*
this); it.first();
return it; }
381 const_sorted_iterator sorted_begin(
void)
const
382 { const_sorted_iterator it(*
this); it.first();
return it; }
383 sorted_iterator sorted_end(
void)
384 { sorted_iterator it(*
this); it.end();
return it; }
385 const_sorted_iterator sorted_end(
void)
const
386 { const_sorted_iterator it(*
this); it.end();
return it; }
387 reverse_sorted_iterator rbegin(
void)
388 {
return reverse_sorted_iterator(this->end()); }
389 const_reverse_sorted_iterator rbegin(
void)
const
390 {
return const_reverse_sorted_iterator(this->end()); }
391 reverse_sorted_iterator rend(
void)
392 {
return reverse_sorted_iterator(this->begin()); }
393 const_reverse_sorted_iterator rend(
void)
const
394 {
return const_reverse_sorted_iterator(this->begin()); }
395 sorted_iterator sorted_first(
void)
396 { sorted_iterator it(*
this); it.first();
return it; }
397 const_sorted_iterator sorted_first(
void)
const
398 { const_sorted_iterator it(*
this); it.first();
return it; }
399 sorted_iterator sorted_last(
void)
400 { sorted_iterator it(*
this); it.last();
return it; }
401 const_sorted_iterator sorted_last(
void)
const
402 { const_sorted_iterator it(*
this); it.last();
return it; }
404 const_sorted_iterator sorted_ge(
const T &elt)
const;
407 template<
typename T,
typename COMP,
unsigned char pks>
408 std::ostream& operator <<(std::ostream& o,
409 dynamic_tree_sorted<T, COMP, pks> &m) {
410 o <<
"Nomber of elt :" << m.card() <<
'\n';
411 o <<
"Index du noeud racine :" << m.root_elt() <<
'\n';
412 for (
size_t i = 0; i < m.size(); ++i)
413 o <<
"elt " << i <<
" left :" <<
int(m.left_elt(i)) <<
" right : "
414 << int(m.right_elt(i)) <<
" balance :" << int(m.balance(i)) <<
'\n';
418 template<
typename T,
typename COMP,
unsigned char pks>
420 dynamic_tree_sorted<T, COMP, pks>::rotate_right(
size_type i) {
421 tree_elt *pni = &(nodes[i]);
423 tree_elt *pnf = &(nodes[f]);
424 pni->l = pnf->r; pnf->r = i; pnf->eq = pni->eq = 0;
428 template<
typename T,
typename COMP,
unsigned char pks>
430 dynamic_tree_sorted<T, COMP, pks>::rotate_left(
size_type i) {
431 tree_elt *pni = &(nodes[i]);
433 tree_elt *pnf = &(nodes[f]);
434 pni->r = pnf->l; pnf->l = i; pnf->eq = pni->eq = 0;
438 template<
typename T,
typename COMP,
unsigned char pks>
440 dynamic_tree_sorted<T, COMP, pks>::rotate_left_right(
size_type i) {
441 tree_elt *pni = &(nodes[i]);
443 tree_elt *pnf = &(nodes[f]);
444 short_type uba = pnf->eq, ubb = nodes[pnf->r].eq;
445 pni->l = rotate_left(f); f = rotate_right(i);
448 nodes[pnf->l].eq =
short_type(uba - 1 - ((ubb == 1) ? 1 : 0));
449 nodes[pnf->r].eq =
short_type(((ubb == -1) ? 1 : 0));
451 if (uba == 0 && ubb == 1)
453 pnf->l = balance_again(pnf->l);
454 if (nodes[pnf->l].eq == 0) pnf->eq = 0;
459 template<
typename T,
typename COMP,
unsigned char pks>
461 dynamic_tree_sorted<T, COMP, pks>::rotate_right_left(
size_type i) {
463 short_type uba = nodes[f].eq, ubb = nodes[nodes[f].l].eq;
464 nodes[i].r = rotate_right(f); f = rotate_left(i);
466 nodes[nodes[f].r].eq =
short_type(uba + 1 + ((ubb == -1) ? 1 : 0));
467 nodes[nodes[f].l].eq =
short_type(((ubb == +1) ? -1 : 0));
469 if (uba == 0 && ubb == -1) {
470 nodes[f].r = balance_again(nodes[f].r);
471 if (nodes[nodes[f].r].eq == 0) nodes[f].eq = 0;
476 template<
typename T,
typename COMP,
unsigned char pks>
478 dynamic_tree_sorted<T, COMP, pks>::balance_again(
size_type i) {
479 tree_elt *pn = &(nodes[i]);
481 case -2 :
if (nodes[pn->l].eq == -1)
return rotate_right(i);
482 else return rotate_left_right(i);
483 case +2 :
if (nodes[pn->r].eq == 1)
return rotate_left(i);
484 else return rotate_right_left(i);
485 case 0 :
case -1 :
case 1 :
return i;
486 default : GMM_ASSERT3(
false,
"internal error");
491 template<
typename T,
typename COMP,
unsigned char pks>
492 void dynamic_tree_sorted<T, COMP, pks>::search_sorted_iterator
493 (
const T &elt, const_sorted_iterator &it)
const{
495 while (it.index() != ST_NIL) {
496 int cp = compar(elt, (*
this)[it.index()]);
497 if (cp < 0) it.down_left();
498 else if (cp > 0) it.down_right();
else break;
502 template<
typename T,
typename COMP,
unsigned char pks>
503 void dynamic_tree_sorted<T, COMP, pks>::find_sorted_iterator
504 (
size_type i, const_sorted_iterator &it)
const {
505 const T *pelt = &((*this)[i]);
507 while (it.index() != ST_NIL) {
508 int cp = compar(*pelt, (*
this)[it.index()]);
509 if (cp == 0) {
if (it.index() == i)
break;
else it.down_left(); }
510 else if (cp < 0) it.down_left();
else it.down_right();
512 if (it.index() == ST_NIL) it.up();
513 while (it.index() != i && it.index() != ST_NIL) ++it;
518 template<
typename T,
typename COMP,
unsigned char pks>
519 void dynamic_tree_sorted<T, COMP, pks>::insert_path
520 (
const T &elt, const_sorted_iterator &it)
const {
522 while (it.index() != ST_NIL) {
523 int cp = compar(elt, (*
this)[it.index()]);
524 if (cp <= 0) it.down_left();
else it.down_right();
528 template<
typename T,
typename COMP,
unsigned char pks>
530 dynamic_tree_sorted<T, COMP, pks>::search_ge(
const T &elt)
const {
531 const_sorted_iterator it(*
this); insert_path(elt, it);
533 if (it.index() == ST_NIL)
534 { it.up();
if (it.index() != ST_NIL && dir == +1) ++it; }
548 template<
typename T,
typename COMP,
unsigned char pks>
549 typename dynamic_tree_sorted<T, COMP, pks>::const_sorted_iterator
550 dynamic_tree_sorted<T, COMP, pks>::sorted_ge(
const T &elt)
const {
551 const_sorted_iterator it(*
this); insert_path(elt, it);
554 if (it.index() != ST_NIL && dir == +1) ++it;
559 template<
typename T,
typename COMP,
unsigned char pks>
561 dynamic_tree_sorted<T, COMP, pks>::memsize(
void)
const {
562 return dynamic_tas<T, pks>::memsize() + nodes.memsize()
563 +
sizeof(dynamic_tree_sorted<T, COMP, pks>);
566 template<
typename T,
typename COMP,
unsigned char pks>
567 void dynamic_tree_sorted<T, COMP, pks>::compact(
void) {
569 while (this->ind.last_true() >= this->ind.card())
570 swap(this->ind.first_false(), this->ind.last_true());
573 template<
typename T,
typename COMP,
unsigned char pks>
574 void dynamic_tree_sorted<T, COMP, pks>::add_index
575 (
size_type i, const_sorted_iterator &it) {
577 if (first_node == ST_NIL)
582 if (dir == -1) nodes[it.index()].l = i;
else nodes[it.index()].r = i;
584 while(it.index() != ST_NIL) {
590 dir = it.direction();
593 case 0 : first_node = f;
break;
594 case -1 : nodes[it.index()].l = f;
break;
595 case +1 : nodes[it.index()].r = f;
break;
599 dir = it.direction();
605 template<
typename T,
typename COMP,
unsigned char pks>
607 dynamic_tree_sorted<T, COMP, pks>::add(
const T &f) {
608 const_sorted_iterator it(*
this); insert_path(f, it);
609 size_type num = dynamic_tas<T,pks>::add(f);
614 template<
typename T,
typename COMP,
unsigned char pks>
void
615 dynamic_tree_sorted<T, COMP, pks>::add_to_index(
size_type i,
const T &f) {
616 if (!(this->index_valid(i) && compar(f, (*
this)[i]) == 0)) {
617 if (this->index_valid(i)) sup(i);
618 dynamic_tas<T,pks>::add_to_index(i, f);
619 const_sorted_iterator it(*
this); insert_path(f, it);
624 template<
typename T,
typename COMP,
unsigned char pks>
626 dynamic_tree_sorted<T, COMP, pks>::add_norepeat
627 (
const T &f,
bool replace,
bool *present) {
628 const_sorted_iterator it(*
this); search_sorted_iterator(f, it);
631 if (present != NULL) *present =
false;
632 num = dynamic_tas<T,pks>::add(f); add_index(num, it);
635 if (present != NULL) *present =
true;
636 if (replace) (*this)[num] = f;
641 template<
typename T,
typename COMP,
unsigned char pks>
642 void dynamic_tree_sorted<T, COMP, pks>::resort(
void) {
643 const_tas_iterator itb
644 = ((
const dynamic_tree_sorted<T, COMP, pks> *)(
this))->tas_begin();
645 const_tas_iterator ite
646 = ((
const dynamic_tree_sorted<T, COMP, pks> *)(
this))->tas_end();
647 const_sorted_iterator it(*
this);
650 { insert_path(*itb, it); add_index(itb.index(), it); ++itb; }
653 template<
typename T,
typename COMP,
unsigned char pks>
654 void dynamic_tree_sorted<T, COMP, pks>::sup_index
655 (
size_type i, const_sorted_iterator &it) {
658 tree_elt *pni = &(nodes[i]), *pnc = 0;
660 if (pni->l == ST_NIL || pni->r == ST_NIL) {
661 f = (pni->l != ST_NIL) ? pni->l : pni->r;
662 dir = it.direction(); it.up(); ic = it.index();
663 if (ic != ST_NIL) pnc = &(nodes[ic]);
665 case 0 : first_node = f;
break;
666 case -1 : pnc->l = f;
break;
667 case +1 : pnc->r = f;
break;
672 dir = it.direction();
673 it--; ni = it.index();
675 case 0 : first_node = ni;
break;
676 case -1 : nodes[f].l = ni;
break;
677 case +1 : nodes[f].r = ni;
break;
679 pnc = &(nodes[ni]); f = pnc->l; *pnc = *pni;
680 dir = it.direction();
681 it.up(); ic = it.index();
if (ic == i) ic = ni; pnc = &(nodes[ic]);
682 if (dir == -1) pnc->l = f;
else pnc->r = f;
685 while (it.index() != ST_NIL) {
689 f = balance_again(ic);
691 dir = it.direction();
692 it.up(); ic = it.index();
if (ic == i) ic = ni;
693 if (ic != ST_NIL) pnc = &(nodes[ic]);
695 case 0 : first_node = f;
break;
696 case -1 : pnc->l = f;
break;
697 case +1 : pnc->r = f;
break;
703 template<
typename T,
typename COMP,
unsigned char pks>
704 void dynamic_tree_sorted<T, COMP, pks>::sup(
size_type i) {
705 GMM_ASSERT2(i < INT_MAX,
"out of range");
706 const_sorted_iterator it(*
this); find_sorted_iterator(i, it);
707 if (it.index() != ST_NIL)
708 { sup_index(i, it); dynamic_tas<T, pks>::sup(i); }
711 template<
typename T,
typename COMP,
unsigned char pks>
713 GMM_ASSERT2(i < INT_MAX && j < INT_MAX,
"out of range");
716 const_sorted_iterator it1(*
this), it2(*
this); it1.end(); it2.end();
718 if (this->index_valid(i)) find_sorted_iterator(i, it1);
719 if (this->index_valid(j)) find_sorted_iterator(j, it2);
721 short_type dir1 = it1.direction(), dir2 = it2.direction();
723 size_type f1 = it1.index(), f2 = it2.index();
725 if (f1!=ST_NIL) {
if (dir1==-1) nodes[f1].l = j;
else nodes[f1].r = j; }
726 if (f2!=ST_NIL) {
if (dir2==-1) nodes[f2].l = i;
else nodes[f2].r = i; }
727 if (first_node==i) first_node=j;
else if (first_node==j) first_node=i;
729 std::swap(nodes[i], nodes[j]);
730 dynamic_tas<T,pks>::swap(i,j);
739 template<
typename T,
typename TAB,
typename COMP>
struct less_index{
742 mutable const T *search_elt;
744 int operator()(
size_t i,
size_t j)
const {
745 return compare( (i == ST_NIL) ? *search_elt : (*tab)[i],
746 (j == ST_NIL) ? *search_elt : (*tab)[j] );
749 less_index(
const TAB &t,
const COMP &c)
750 { compare = c; tab = &t; }
756 template<
typename T,
typename TAB,
typename COMP = gmm::less<T>,
unsigned char pks = 5>
757 class dynamic_tree_sorted_index :
public
758 dynamic_tree_sorted<size_t, less_index<T,TAB,COMP>, pks> {
762 dynamic_tree_sorted<size_t, less_index<T,TAB,COMP>, pks>
::size_type
767 typedef dynamic_tree_sorted<size_t, less_index<T,TAB,COMP>, pks> dts_type;
771 dynamic_tree_sorted_index(TAB &t, COMP cp = COMP())
772 : dts_type(less_index<T,TAB,COMP>(t, cp)) { }
774 void change_tab(TAB &t, COMP cp = COMP())
775 { this->comparator() = less_index<T,TAB,COMP>(t, cp); }
778 this->compar.search_elt = &elt;
779 return dts_type::search(ST_NIL);
781 size_type search_ge(
const T &elt)
const {
782 this->compar.search_elt = &elt;
783 return dts_type::search_ge(ST_NIL);
786 typename dts_type::const_sorted_iterator it(*
this); (*this)[i] = i;
787 this->ind[i] =
true; insert_path(i, it); add_index(i, it);
return i;