19 #ifndef REDBLACK_H_PREDOEHL_12_DEC_2011_VISION
20 #define REDBLACK_H_PREDOEHL_12_DEC_2011_VISION 1
22 #include <l/l_sys_lib.h>
23 #include <l/l_sys_io.h>
24 #include <l/l_debug.h>
42 #define REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY 1
44 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
164 template <
typename SATELLITE_TYPE >
178 BLACKHEIGHT_BAD = -1,
179 LOCATOR_BASE = 987000
183 typedef std::map< Loc_tp, char > LocCensus_tp;
229 bool operator<(
const Node& other )
const
231 return key < other.key;
242 void you_are_my_child( Node* child, Node* Node::* branch )
245 this ->* branch = child;
246 child -> parent =
this;
250 void link_left_child( Node* child )
252 you_are_my_child( child, & Node::left );
256 void link_right_child( Node* child )
258 you_are_my_child( child, & Node::right );
266 Key_tp operator()(
const Key_tp&
a,
const Node& n ) {
return a+n.key; }
309 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
310 std::vector< Node* > location_list;
312 typedef std::map< Loc_tp, Node* > LocationList;
313 typedef typename LocationList::const_iterator LLCI;
315 LocationList location_list;
318 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
319 std::vector< Loc_tp > free_locator_list;
324 void chatter(
const char* s )
const
327 if ( VERBOSE )
KJB(TEST_PSE((
"CHATTER: %s\n", s )));
331 void enter(
const char* s )
const
333 if ( VERBOSE )
KJB(TEST_PSE((
"CHATTER: Entering %s\n", s )));
337 bool fail(
const char *s )
const
344 bool fail(
int nnn )
const
346 KJB(TEST_PSE((
"FAIL: line %d\n", nnn )));
351 void chatter(
const char* )
const {}
355 void enter(
const char* )
const {}
358 bool fail(
const char* )
const {
return false; }
361 bool fail(
int )
const {
return false; }
367 Loc_tp obtain_avail_locator()
369 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
370 Loc_tp nuloc = location_list.size();
372 if ( free_locator_list.size() )
375 nuloc = free_locator_list.back();
376 free_locator_list.pop_back();
380 location_list.push_back( 00 );
385 if (location_list.empty())
return 0;
387 LLCI
i = location_list.end();
389 return 1 + i -> first;
394 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
403 void opportunistic_cleanup_of_idle_locators()
405 while ( location_list.size()
406 && 00 == location_list.back()
407 && free_locator_list.size()
408 && 1 + free_locator_list.back() == location_list.size()
411 location_list.pop_back();
412 free_locator_list.pop_back();
418 void release_locator(
Loc_tp loc )
420 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
421 KJB(
ASSERT( loc < location_list.size() ));
424 free_locator_list.push_back( loc );
425 location_list[ loc ] = 00;
428 if ( free_locator_list.size() & ~0xFFF
429 &&
size() < free_locator_list.size()>>3
430 && 00 == location_list.back()
433 std::sort(free_locator_list.begin(), free_locator_list.end());
434 opportunistic_cleanup_of_idle_locators();
440 std::reverse(free_locator_list.begin(), free_locator_list.end());
446 location_list.erase(loc);
453 Node* new_node(
const Key_tp& key,
const Sat_tp& sat,
bool black )
455 const Loc_tp nuloc = obtain_avail_locator();
456 Node* nn =
new Node( key, sat, black, & m_nil, & m_nil, nuloc );
457 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
458 KJB(
ASSERT( nuloc < location_list.size() ));
459 KJB(
ASSERT( 00 == location_list.at( nuloc ) ));
462 location_list[ nuloc ] = nn;
468 Node* new_node(
const Node& old_node )
470 return new_node( old_node.key, old_node.sat, old_node.is_black );
475 bool loc_list_good_here(
const Node* ppp )
const
477 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
478 return ppp && location_list.at( ppp -> locator ) == ppp;
480 if (00 == ppp)
return false;
481 LLCI i = location_list.find( ppp -> locator );
482 return i != location_list.end() && i -> second == ppp;
488 void dispose( Node* ppp )
491 KJB(
ASSERT( loc_list_good_here( ppp ) ));
492 const Loc_tp ploc = ppp -> locator;
493 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
494 KJB(
ASSERT( location_list.at( ploc ) == ppp ));
496 KJB(
ASSERT( location_list[ ploc ] == ppp ));
498 release_locator( ploc );
504 bool is_nil(
const Node* ppp )
const
506 return ppp == & m_nil;
511 bool is_not_nil(
const Node* ppp )
const
513 return ppp != & m_nil;
518 bool are_both_children_nil(
const Node* ppp )
const
522 && is_nil( ppp -> left )
523 && is_nil( ppp -> right );
533 int blackheight_in_linear_time(
const Node* ppp )
const
541 int bh = blackheight_in_linear_time( ppp -> left );
543 if ( bh != BLACKHEIGHT_BAD
544 && bh == blackheight_in_linear_time( ppp -> right )
547 return bh + ( ppp -> is_black ? 1 : 0 );
550 return BLACKHEIGHT_BAD;
560 void recursive_destroy( Node* ppp )
562 if ( ppp && is_not_nil( ppp ) )
564 recursive_destroy( ppp -> left );
565 recursive_destroy( ppp -> right );
572 void make_it_a_real_tree_now()
577 std::sort( root, root + TREE_THRESH );
578 Node sorty[ TREE_THRESH ];
579 std::copy( root, root + TREE_THRESH, sorty );
584 root = new_node( sorty[ 3 ] );
585 root -> link_left_child( new_node( sorty[ 1 ] ) );
586 root -> link_right_child( new_node( sorty[ 5 ] ) );
587 root -> left -> link_left_child( new_node( sorty[ 0 ] ) );
588 root -> left -> link_right_child( new_node( sorty[ 2 ] ) );
589 root -> right -> link_left_child( new_node( sorty[ 4 ] ) );
590 root -> right -> link_right_child( new_node( sorty[ 6 ] ) );
591 root -> parent = m_nil.parent = 00;
594 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
595 release_locator( root -> locator );
596 release_locator( root -> left -> locator );
597 release_locator( root -> right -> locator );
598 release_locator( root -> left -> left -> locator );
599 release_locator( root -> left -> right -> locator );
600 release_locator( root -> right -> left -> locator );
601 release_locator( root -> right -> right -> locator );
603 location_list.clear();
607 location_list[ sorty[ 3 ].locator ] = root;
608 location_list[ sorty[ 1 ].locator ] = root -> left;
609 location_list[ sorty[ 5 ].locator ] = root -> right;
610 location_list[ sorty[ 0 ].locator ] = root -> left -> left;
611 location_list[ sorty[ 2 ].locator ] = root -> left -> right;
612 location_list[ sorty[ 4 ].locator ] = root -> right -> left;
613 location_list[ sorty[ 6 ].locator ] = root -> right -> right;
616 root -> locator = sorty[ 3 ].locator;
617 root -> left -> locator = sorty[ 1 ].locator;
618 root -> right -> locator = sorty[ 5 ].locator;
619 root -> left -> left -> locator = sorty[ 0 ].locator;
620 root -> left -> right -> locator = sorty[ 2 ].locator;
621 root -> right -> left -> locator = sorty[ 4 ].locator;
622 root -> right -> right -> locator = sorty[ 6 ].locator;
624 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
626 opportunistic_cleanup_of_idle_locators();
631 root -> left -> update_sum();
632 root -> right -> update_sum();
633 root -> update_sum();
665 int insert_parent( Node** toparent,
bool pn_left, Node* n00b )
667 KJB(
ASSERT( n00b && toparent && *toparent ));
668 Node* parent = *toparent;
670 Node* Node::* branch = pn_left ? & Node::left : & Node::right;
671 if ( is_nil( parent ->* branch ) )
674 parent -> you_are_my_child( n00b, branch );
675 parent ->
sum += n00b ->
sum;
681 int rc = insert_gp( toparent, pn_left, n00b );
687 KJB(
ASSERT( 0 == rc || 2 == rc || 4 == rc ));
688 KJB(
ASSERT( rc != 2 || ( parent ->* branch ) -> is_red() ));
689 KJB(
ASSERT( rc != 4 || parent -> is_red() ));
698 return insert_gp( toparent, pn_left, n00b ) >> 1;
742 int insert_gp( Node** togramp,
bool gp_left, Node* n00b )
744 KJB(
ASSERT( n00b && togramp && *togramp ));
746 Node *gramp = *togramp,
747 **toparent = gp_left ? & gramp -> left : & gramp -> right;
749 gramp ->
sum += n00b ->
sum;
752 Node *parent = *toparent;
755 bool pn_left = *n00b < *parent;
773 int rc = insert_parent( toparent, pn_left, n00b );
774 KJB(
ASSERT( 0 == rc || 1 == rc || 2 == rc ));
782 return rb_balance( togramp, gp_left, pn_left, rc );
787 Node* Node::* opposite_direction( Node* Node::* some_direction )
const
789 return some_direction == & Node::left ? & Node::right : & Node::left;
829 void unzigzag( Node* gramp, Node* Node::* p_branch )
831 Node* Node::* u_branch = opposite_direction( p_branch );
834 KJB(
ASSERT( is_not_nil( gramp ->* p_branch ) ));
835 KJB(
ASSERT( is_not_nil( gramp ->* p_branch ->* u_branch ) ));
837 Node *oldparent = gramp ->* p_branch,
838 *oldchild = oldparent ->* u_branch,
839 *med_tree = oldchild ->* p_branch;
841 gramp -> you_are_my_child( oldchild, p_branch );
842 oldchild -> you_are_my_child( oldparent, p_branch );
844 oldparent ->* u_branch = med_tree;
845 if ( is_not_nil( med_tree ) )
847 med_tree -> parent = oldparent;
853 oldparent -> update_sum();
854 oldchild -> update_sum();
897 void rotate( Node** togramp, Node* Node::* p_branch )
901 Node* Node::* u_branch = opposite_direction( p_branch );
902 Node* oldgramp = *togramp;
905 KJB(
ASSERT( is_not_nil( oldgramp ->* p_branch ) ));
907 Node *oldparent = oldgramp ->* p_branch,
908 *medmed_tree = oldparent ->* u_branch;
910 KJB(
ASSERT( oldparent -> parent == oldgramp ));
913 *togramp = oldparent;
916 oldparent -> parent = oldgramp -> parent;
917 oldparent -> you_are_my_child( oldgramp, u_branch );
919 oldgramp ->* p_branch = medmed_tree;
920 if ( is_not_nil( medmed_tree ) )
922 medmed_tree -> parent = oldgramp;
931 std::swap( oldgramp -> is_black, oldparent -> is_black );
933 oldgramp -> update_sum();
934 oldparent -> update_sum();
966 int rb_balance( Node** togramp,
bool gp_left,
bool pn_left,
int red_child )
975 if ( red_child != 1 )
982 Node* Node::* gp_branch = gp_left ? & Node::left : & Node::right;
984 Node *gramp = *togramp,
985 *parent = gramp ->* gp_branch,
986 *uncle = gramp ->* opposite_direction( gp_branch );
989 if ( parent -> is_black )
995 if ( uncle -> is_black )
998 if ( gp_left != pn_left )
1000 unzigzag( gramp, gp_branch );
1003 rotate( togramp, gp_branch );
1009 uncle -> is_black = parent -> is_black =
true;
1010 gramp -> is_black =
false;
1016 void dbp_indent(
int depth, std::ostream& os )
const
1019 static const char* INDENT =
"\t";
1020 for (
int iii = 0; iii < depth; ++iii )
1028 void db_print_child(
1031 Node* Node::* branchpp,
1032 const char* branchss,
1036 dbp_indent( depth, os );
1037 os << branchss <<
" subtree:";
1038 if ( is_nil( ppp ->* branchpp ) )
1044 if ( ppp != root && ( ppp ->* branchpp ) -> parent != ppp )
1046 os <<
" BROKEN!!!! ";
1049 recursive_db_print( ppp ->* branchpp, 1 + depth, os );
1055 void recursive_db_print(
1061 if ( is_nil( ppp ) )
1066 dbp_indent( depth, os );
1067 os <<
"key=" << ppp -> key <<
", sum=" << ppp ->
sum
1068 <<
", color=" << ( ppp -> is_black ?
"BLACK" :
"red" )
1069 <<
", sat=" << ppp -> sat
1070 <<
", loc=" << ppp -> locator;
1072 if ( ! dictionary_is_small_linear_array() )
1074 os <<
", blackheight=" << blackheight_in_linear_time( ppp );
1076 else if ( ! are_both_children_nil( ppp ) )
1078 os <<
", WARNING: children are not nil";
1081 if ( are_both_children_nil( ppp ) )
1086 os <<
", left=" << ppp -> left <<
", right=" << ppp -> right <<
'\n';
1088 db_print_child( ppp, depth, & Node::left,
"Left", os );
1089 db_print_child( ppp, depth, & Node::right,
"Right", os );
1095 bool red_node_has_red_child_in_linear_time(
const Node* ppp )
const
1098 if ( is_nil( ppp ) || are_both_children_nil( ppp ) )
1102 if ( ppp -> is_red() && ppp -> left -> is_red() )
1106 if ( ppp -> is_red() && ppp -> right -> is_red() )
1110 return red_node_has_red_child_in_linear_time( ppp -> left )
1111 || red_node_has_red_child_in_linear_time( ppp -> right );
1116 bool sums_are_correct_in_linear_time(
const Node* ppp )
const
1119 if ( is_nil( ppp ) )
return true;
1121 if ( is_not_nil( ppp -> left ) ) sts += ppp -> left ->
sum;
1122 if ( is_not_nil( ppp -> right ) ) sts += ppp -> right ->
sum;
1124 if ( sts != ppp ->
sum )
1126 chatter(
"internal sums are incorrect" );
1129 return sts == ppp ->
sum
1130 && sums_are_correct_in_linear_time( ppp -> left )
1131 && sums_are_correct_in_linear_time( ppp -> right );
1136 bool sums_are_close_enough_in_linear_time(
const Node* ppp )
const
1138 const Key_tp SMALL = 1e-3;
1140 if ( is_nil( ppp ) )
1144 if ( is_not_nil( ppp -> left ) ) sts += ppp -> left ->
sum;
1145 if ( is_not_nil( ppp -> right ) ) sts += ppp -> right ->
sum;
1147 Key_tp rrr = fabs( sts - ppp ->
sum )/(fabs( sts )+fabs( ppp ->
sum ));
1150 if ( !( sts == ppp ->
sum || rrr < SMALL ) )
1152 chatter(
"internal sums are inadequately accurate" );
1153 std::ostringstream ess;
1154 ess <<
"rrr=" <<rrr <<
" which exceeds SMALL=" << SMALL <<
'\n';
1155 chatter( ess.str().c_str() );
1156 return fail( __LINE__ );
1160 return ( sts == ppp ->
sum || rrr < SMALL )
1161 && sums_are_close_enough_in_linear_time( ppp -> left )
1162 && sums_are_close_enough_in_linear_time( ppp -> right );
1194 for (
size_t iii = 0; iii < m_size; ++iii )
1196 if ( root[ iii ].key == qkey )
1198 if ( sat_out ) *sat_out = root[ iii ].sat;
1199 if ( loc_out ) *loc_out = root[ iii ].locator;
1200 if ( ix ) *ix = iii;
1201 KJB(
ASSERT( loc_list_good_here( root + iii ) ));
1221 if ( is_nil( ppp ) )
1225 if ( qkey == ppp -> key )
1227 if ( sat_out ) *sat_out = ppp -> sat;
1228 if ( loc_out ) *loc_out = ppp -> locator;
1231 Node* Node::* branch= qkey < ppp -> key ? & Node::left : & Node::right;
1232 return tree_search( qkey, sat_out, ppp ->* branch, loc_out );
1245 Node* recursive_condense( Node* tree, Node*
dest )
1248 if ( is_nil( tree ) )
1254 Node* d2 = recursive_condense( tree -> left, dest );
1258 Node* d3 = recursive_condense( tree -> right, d2 );
1265 struct GetLocator {
Loc_tp operator()(
const Node& n) {
return n.locator;} };
1276 Redblack_subtree_sum< SATELLITE_TYPE >*
const tree;
1279 Leafify(Redblack_subtree_sum< SATELLITE_TYPE >* t) : tree(t) {}
1281 void operator()(Node& node)
const
1283 node.left = node.right = & tree -> m_nil;
1285 node.is_black =
true;
1286 node.sum = node.key;
1289 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
1290 KJB(
ASSERT(node.locator < tree -> location_list.size()));
1291 KJB(
ASSERT( 00 == tree -> location_list[ node.locator ] ));
1293 tree -> location_list[ node.locator ] = &node;
1298 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
1310 void rebuild_locator_list_for_linear_array()
1313 std::vector< Loc_tp > locs(
size() );
1314 std::transform(root, root+
size(), locs.begin(), GetLocator());
1315 std::sort(locs.begin(), locs.end());
1318 KJB(
ASSERT(std::adjacent_find(locs.begin(),locs.end()) == locs.end()));
1325 const size_t llsz = 1 + locs.back();
1326 location_list.assign(llsz, 00);
1331 std::vector< Loc_tp > panloc(llsz);
1332 for (
size_t i = 0; i < llsz; ++
i)
1336 free_locator_list.resize(location_list.size() - locs.size());
1338 typename std::vector< Loc_tp >::iterator z =
1340 std::set_difference(panloc.begin(), panloc.end(),
1341 locs.begin(), locs.end(),
1342 free_locator_list.begin());
1343 KJB(
ASSERT(free_locator_list.end() == z));
1345 std::reverse(free_locator_list.begin(), free_locator_list.end());
1352 void condense_into_linear_array()
1363 Node *la =
new Node[
size() ];
1367 recursive_condense( root, la );
1369 recursive_destroy( root );
1372 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
1374 rebuild_locator_list_for_linear_array();
1380 std::for_each(root, root +
size(), Leafify(
this));
1385 Node** to_parent_link( Node* ppp )
1392 KJB(
ASSERT( ppp && is_not_nil( ppp ) ));
1394 Node* parent = ppp -> parent;
1395 KJB(
ASSERT( parent && is_not_nil( parent ) ));
1396 KJB(
ASSERT( parent -> right == ppp || parent -> left == ppp ));
1398 return parent -> left == ppp ? & parent -> left : & parent -> right;
1403 Node* Node::* parent_branch_to_me( Node* ppp )
const
1407 KJB(
ASSERT( ppp -> parent -> right == ppp
1408 || ppp -> parent -> left == ppp ));
1409 return ppp -> parent -> right == ppp ? & Node::right : & Node::left;
1435 Node* splice_me( Node* ppp, Node* Node::* par_br, Node* Node::* child_br )
1439 Node *child_p = ppp ->* child_br,
1440 *par_p = ppp -> parent;
1441 KJB(
ASSERT( par_p && is_not_nil( par_p ) ));
1443 KJB(
ASSERT( is_nil( ppp ->* opposite_direction( child_br ) ) ));
1445 KJB(
ASSERT( is_nil( child_p ) || ppp == child_p -> parent ));
1458 par_p -> you_are_my_child( child_p, par_br );
1460 KJB(
ASSERT( (ppp ->* child_br) -> parent == ppp -> parent ));
1461 KJB(
ASSERT( ppp -> parent ->* par_br == ppp ->* child_br ));
1468 Node* semiauto_splice( Node* ppp, Node* Node::* child_br )
1472 KJB(
ASSERT( is_nil( ppp ->* opposite_direction( child_br ) ) ));
1474 || ppp == ( ppp ->* child_br ) -> parent ));
1475 root = ppp ->* child_br;
1478 return splice_me( ppp, parent_branch_to_me( ppp ), child_br );
1493 Node* fully_auto_splice( Node* ppp, Node ** tochild )
1495 if ( is_nil( ppp -> left ) )
1497 *tochild = ppp -> right;
1498 return semiauto_splice( ppp, & Node::right );
1500 if ( is_nil( ppp -> right ) )
1502 *tochild = ppp -> left;
1503 return semiauto_splice( ppp, & Node::left );
1529 Node* del_child_not_target( Node* target, Node** to_child )
1534 KJB(
ASSERT( target && is_not_nil( target ) ));
1535 KJB(
ASSERT( is_not_nil( target -> right ) ));
1539 Node *vic = target -> right;
1540 for ( ; is_not_nil( vic -> left ); vic = vic -> left )
1543 KJB(
ASSERT( is_not_nil( vic ) && is_nil( vic -> left ) ));
1549 target -> key = vic -> key;
1550 target -> sat = vic -> sat;
1551 Loc_tp &TaLo( target -> locator ), &ViLo( vic -> locator );
1552 std::swap( location_list[ TaLo ], location_list[ ViLo ] );
1556 for ( Node* ppp = target -> right; ppp != vic; ppp = ppp -> left )
1559 ppp ->
sum -= vic -> key;
1563 *to_child = vic -> right;
1564 return semiauto_splice( vic, & Node::right );
1569 void resolve_double_black( Node* xblack )
1576 KJB(
ASSERT( root && is_not_nil( root ) ));
1578 if ( xblack -> is_red() )
1581 xblack -> is_black =
true;
1585 if ( xblack == root )
1591 Node* Node::* xb_br = parent_branch_to_me( xblack );
1592 Node* Node::* sib_br = opposite_direction( xb_br );
1593 Node* sib = xblack -> parent ->* sib_br;
1594 KJB(
ASSERT( sib && is_not_nil( sib ) ));
1597 if ( sib -> is_red() )
1599 return case_of_the_red_sibling(
1608 Node *near_nephew = sib ->* xb_br,
1609 *far_nephew = sib ->* sib_br;
1610 KJB(
ASSERT( far_nephew && near_nephew ));
1613 if ( far_nephew -> is_red() )
1615 return case_of_the_far_red_nephew( sib, xb_br );
1618 if ( near_nephew -> is_black )
1620 return case_of_the_black_sib_and_nephews( sib );
1623 return case_of_the_near_red_nephew( xblack, sib, xb_br );
1639 void case_of_the_black_sib_and_nephews( Node* sib )
1644 KJB(
ASSERT( sib && is_not_nil( sib ) && sib -> is_black ));
1645 KJB(
ASSERT( sib -> left && sib -> left -> is_black ));
1646 KJB(
ASSERT( sib -> right && sib -> right -> is_black ));
1648 sib -> is_black =
false;
1651 return resolve_double_black( sib -> parent );
1675 void case_of_the_far_red_nephew( Node* oldsib, Node* Node::* xb_br )
1682 Node* Node::* sib_br = opposite_direction( xb_br );
1686 Node *oldparent = oldsib -> parent,
1687 *old_far_nephew = oldsib ->* sib_br;
1688 KJB(
ASSERT( oldparent && is_not_nil( oldparent ) ));
1689 KJB(
ASSERT( oldsib == oldparent ->* sib_br ));
1691 KJB(
ASSERT( old_far_nephew -> is_red() ));
1693 rotate( to_parent_link( oldparent ), sib_br );
1694 old_far_nephew -> is_black =
true;
1715 void case_of_the_near_red_nephew(
1724 KJB(
ASSERT( xblack -> parent == oldsib -> parent ));
1725 KJB(
ASSERT( oldsib && is_not_nil( oldsib ) && oldsib -> is_black ));
1726 KJB(
ASSERT( oldsib -> left && oldsib -> right ));
1729 Node *old_red_nef = ( oldsib ->* xb_br ),
1730 *parent = xblack -> parent;
1733 KJB(
ASSERT( ( oldsib ->* opposite_direction( xb_br ) ) -> is_black ));
1742 unzigzag( parent, opposite_direction( xb_br ) );
1744 oldsib -> is_black =
false;
1746 Node *& new_blk_sib = old_red_nef;
1747 new_blk_sib -> is_black =
true;
1750 KJB(
ASSERT( new_blk_sib == parent ->* opposite_direction( xb_br ) ));
1751 KJB(
ASSERT( oldsib == new_blk_sib ->* opposite_direction( xb_br ) ));
1752 return case_of_the_far_red_nephew( new_blk_sib, xb_br );
1778 void case_of_the_red_sibling(
1789 KJB(
ASSERT( sib && is_not_nil( sib ) ));
1790 KJB(
ASSERT( xblack -> parent == sib -> parent ));
1791 KJB(
ASSERT( xblack -> is_black && sib -> is_red() ));
1795 Node* xb_parent = xblack -> parent;
1797 Node* Node::* sib_br = opposite_direction( xb_br );
1798 rotate( to_parent_link( xb_parent ), sib_br );
1802 xblack -> parent = xb_parent;
1806 KJB(
ASSERT( xb_parent == sib ->* xb_br ));
1809 KJB(
ASSERT( (xb_parent ->* sib_br) -> is_black ));
1810 KJB(
ASSERT( (xb_parent ->* xb_br ) == xblack ));
1813 resolve_double_black( xblack );
1832 void kill_a_node( Node* target )
1838 KJB(
ASSERT( target && is_not_nil( target ) ));
1839 const Key_tp& query_key( target -> key );
1841 for ( Node* ppp = target; ppp != root; ppp = ppp -> parent )
1843 ppp ->
sum -= query_key;
1845 root ->
sum -= query_key;
1848 Node *xblack, *tar2 = fully_auto_splice( target, & xblack );
1851 KJB(
ASSERT( 00 == tar2 || 00 == m_nil.parent || is_nil( xblack ) ));
1852 KJB(
ASSERT( 00 == tar2 || m_nil.parent || is_not_nil( xblack ) ));
1856 tar2 = del_child_not_target( target, & xblack );
1860 KJB(
ASSERT( is_nil( tar2 -> left ) || is_nil( tar2 -> right ) ));
1861 KJB(
ASSERT( is_nil( tar2 -> left ) || xblack == tar2 -> left ));
1862 KJB(
ASSERT( is_nil( tar2 -> right ) || xblack == tar2 -> right ));
1863 KJB(
ASSERT( tar2 == root || xblack -> parent == tar2 -> parent ));
1865 || tar2 -> parent -> left == xblack
1866 || tar2 -> parent -> right == xblack ));
1868 if ( tar2 -> is_black )
1870 resolve_double_black( xblack );
1878 bool dictionary_is_small_linear_array()
const
1880 return size() <= TREE_THRESH;
1885 int blackheight_in_linear_time()
const
1890 if ( dictionary_is_small_linear_array() )
1894 return blackheight_in_linear_time( root );
1898 bool red_node_has_red_child_in_linear_time()
const
1903 return red_node_has_red_child_in_linear_time( root );
1907 bool sums_are_correct_in_linear_time()
const
1912 return sums_are_correct_in_linear_time( root );
1917 Node* recursive_copy(
1919 const Redblack_subtree_sum< SATELLITE_TYPE >& st
1923 if ( st.is_nil( src ) )
1928 Node* my_copy =
new Node( *src );
1930 my_copy -> link_left_child( recursive_copy( src -> left, st ) );
1931 my_copy -> link_right_child( recursive_copy( src -> right, st ) );
1934 const Loc_tp l = src -> locator;
1935 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
1936 KJB(
ASSERT( l < location_list.size() ));
1937 location_list.at( l ) = my_copy;
1939 location_list[ l ] = my_copy;
1948 bool is_bst_in_linear_time()
const
1953 return is_bst_in_linear_time( root, -KMAX, +KMAX );
1958 bool is_bst_in_linear_time(
1965 if ( is_nil( ppp ) )
1969 const Key_tp& kii = ppp -> key;
1976 if ( kii < min || max < kii )
1981 const Node *pl = ppp -> left,
1984 return ( is_nil( pl ) || pl -> parent == ppp )
1985 && ( is_nil( pr ) || pr -> parent == ppp )
1986 && is_bst_in_linear_time( pr, kii, max )
1987 && is_bst_in_linear_time( pl, min, kii );
1992 void locators_scan_nlogn_time(
1993 LocCensus_tp* census_ptr,
1999 LocCensus_tp& census( *census_ptr );
2000 if ( is_nil( ppp ) )
2004 census[ ppp -> locator ] += 1;
2005 locators_scan_nlogn_time( census_ptr, ppp -> left );
2006 locators_scan_nlogn_time( census_ptr, ppp -> right );
2010 bool locators_valid_in_nlogn_time()
const
2013 typedef typename LocCensus_tp::iterator LCI;
2015 LocCensus_tp census;
2018 if ( dictionary_is_small_linear_array() )
2020 for (
size_t iii = 0; iii <
size(); ++iii )
2022 Loc_tp loc = root[ iii ].locator;
2024 if ( ! loc_list_good_here( root + iii ) )
2026 return fail( __LINE__ );
2032 locators_scan_nlogn_time( & census, root );
2040 for ( LCI iii = census.begin(); iii != census.end(); ++iii )
2042 Loc_tp loc = iii -> first;
2043 if ( iii -> second != 1 )
2045 return fail( __LINE__ );
2047 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2048 Node* ppp = location_list[ loc ];
2049 if ( 00 == ppp || ppp -> locator != loc )
2051 return fail( __LINE__ );
2054 LLCI i = location_list.find(loc);
2055 if ( location_list.end() == i
2056 || 00 == i -> second
2057 || i -> first != loc
2060 return fail( __LINE__ );
2065 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2067 LocCensus_tp unused;
2068 for (
size_t iii = 0; iii < free_locator_list.size(); ++iii )
2070 unused[ free_locator_list[ iii ] ] += 1;
2079 for ( LCI iii = unused.begin(); iii != unused.end(); ++iii )
2081 Loc_tp loc = iii -> first;
2083 if ( iii -> second != 1 )
return fail( __LINE__ );
2085 if ( census[ loc ] != 0 )
2087 KJB(TEST_PSE((
"census loc is %d\n",
int(census[loc]) )));
2088 return fail( __LINE__ );
2091 if ( location_list.size() <= loc )
return fail( __LINE__ );
2093 if ( location_list[ loc ] != 00 )
return fail( __LINE__ );
2102 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2103 for (
Loc_tp loc = 0; loc < location_list.size(); ++loc )
2105 if ( location_list[ loc ] )
2107 if ( census[ loc ] != 1 )
2109 std::ostringstream oss;
2110 oss <<
"locator index " << loc
2111 <<
" has\n\tcensus value " << int(census[loc])
2112 <<
"\n\tptr value " << location_list[loc]
2113 <<
"\n\tptr loc " << location_list[loc]->locator
2115 KJB(TEST_PSE((
"%s\n", oss.str().c_str() )));
2116 return fail( __LINE__ );
2119 else if ( unused[ loc ] != 1 )
2121 return fail( __LINE__ );
2125 for (LLCI i = location_list.begin(); i != location_list.end(); ++
i)
2127 const Loc_tp loc = i -> first;
2128 if (00 == i -> second)
return fail( __LINE__ );
2130 if ( census[ loc ] != 1 )
2132 std::ostringstream oss;
2133 oss <<
"locator index " << loc
2134 <<
" has\n\tcensus value " << int(census[loc])
2135 <<
"\n\tptr value " << i -> second
2136 <<
"\n\tptr loc " << i -> second -> locator
2138 KJB(TEST_PSE((
"%s\n", oss.str().c_str() )));
2139 return fail( __LINE__ );
2152 const int BLACK = 1;
2153 Loc_tp nuloc = obtain_avail_locator();
2154 root[ m_size ] = Node( key, sat, BLACK, & m_nil, & m_nil, nuloc );
2155 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2156 KJB(
ASSERT( 00 == location_list.at( nuloc ) ));
2158 location_list[ nuloc ] = root + m_size;
2167 if ( TREE_THRESH ==
size() )
2169 make_it_a_real_tree_now();
2171 Node* n00b = new_node( key, sat, 0 );
2172 insert_gp( &root, *n00b < *root, n00b );
2173 root -> is_black =
true;
2177 return n00b -> locator;
2182 void db_print_locators()
const
2185 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2186 KJB(TEST_PSE((
"Locs in use: " )));
2187 for (
size_t iii = 0; iii < location_list.size(); ++iii )
2189 if ( location_list.at( iii ) )
2191 KJB(TEST_PSE((
"%s%d", (iii ?
"," :
""), iii )));
2194 KJB(TEST_PSE((
"\nLocs avail: " )));
2195 for (
size_t iii = 0; iii < free_locator_list.size(); ++iii )
2197 KJB(TEST_PSE((
"%s%d", (iii ?
",":
""),
2198 free_locator_list.at( iii ) )));
2201 KJB(TEST_PSE((
"Locs in use:" )));
2202 for (LLCI i = location_list.begin(); i != location_list.end(); ++
i)
2204 KJB(TEST_PSE((
" %u", i -> first)));
2207 KJB(TEST_PSE((
"\n" )));
2213 bool del_array_elt(
size_t index )
2217 Loc_tp loc = root[ index ].locator;
2218 release_locator( loc );
2227 if ( index < m_size )
2230 root[ index ] = root[ m_size ];
2232 KJB(
ASSERT( location_list[ root[index].locator ] == root+m_size ));
2233 location_list[ root[ index ].locator ] = root + index;
2246 bool del_tree_node( Node* ppp )
2248 KJB(
ASSERT( ppp && loc_list_good_here( ppp ) ));
2254 if ( TREE_THRESH == m_size )
2256 condense_into_linear_array();
2264 Node* Node::* branch,
2265 const Node* ( *pf )(
const Node*,
const Node* )
2274 if ( dictionary_is_small_linear_array() )
2276 const Node* ppp = (*pf)( root, root +
size() );
2277 return LOCATOR_BASE + ppp -> locator;
2283 for ( ppp = root; ppp && is_not_nil( ppp ->* branch );
2284 ppp = ppp ->* branch )
2288 KJB(
ASSERT( ppp && is_nil( ppp ->* branch ) ));
2289 return LOCATOR_BASE + ppp -> locator;
2294 Loc_tp array_seek_cukes(
Key_tp cumulative_keysum )
const
2297 std::vector< Node > dicopy( root, root +
size() );
2298 std::sort( dicopy.begin(), dicopy.end() );
2300 Node dicopy[ TREE_THRESH ];
2301 std::copy(root, root +
size(), dicopy);
2302 std::sort( dicopy, dicopy +
size() );
2306 for (
size_t iii = 0; iii <
size(); ++iii )
2308 if ( cumulative_keysum <= ( sum_so_far += dicopy[ iii ].key ) )
2310 return dicopy[ iii ].locator;
2313 KJB(
ASSERT( sum_so_far < cumulative_keysum ));
2314 chatter(
"sought a cumulative key sum larger than sum of all keys 1" );
2318 return dicopy.at(
int(
size()) - 1 ).locator;
2320 return dicopy[
size() - 1 ].locator;
2326 Loc_tp tree_seek_cukes(
const Node* ppp,
Key_tp cumulative_keysum )
const
2328 KJB(
ASSERT( ppp && is_not_nil( ppp ) ));
2329 if ( are_both_children_nil( ppp ) )
2331 if ( ppp -> key < cumulative_keysum )
2333 chatter(
"sought a cumulative key sum larger than "
2334 "sum of all keys 2" );
2336 return ppp -> locator;
2338 const Key_tp lsum = is_not_nil( ppp -> left ) ? ppp -> left ->
sum : 0;
2340 if ( is_not_nil( ppp -> left ) && cumulative_keysum <= lsum )
2342 return tree_seek_cukes( ppp -> left, cumulative_keysum );
2344 cumulative_keysum -= lsum;
2346 if ( cumulative_keysum <= ppp -> key )
2348 return ppp -> locator;
2351 if ( is_nil( ppp -> right ) )
2353 chatter(
"sought a cumulative key sum larger than "
2354 "sum of all keys 3" );
2355 return ppp -> locator;
2357 cumulative_keysum -= ppp -> key;
2359 return tree_seek_cukes( ppp -> right, cumulative_keysum );
2373 void copy_tree_into_empty(
2374 const Redblack_subtree_sum< SATELLITE_TYPE >& tree
2378 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2380 KJB(
ASSERT(0 == free_locator_list.size()));
2385 if ( 0 == tree.size() )
return;
2390 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2391 location_list.resize(tree.location_list.size());
2392 free_locator_list.resize(tree.free_locator_list.size());
2393 std::copy(tree.free_locator_list.begin(),
2394 tree.free_locator_list.end(), free_locator_list.begin());
2396 m_size = tree.size();
2398 if ( tree.dictionary_is_small_linear_array() )
2400 root =
new Node[ TREE_THRESH ];
2401 std::copy(tree.root, tree.root + tree.size(), root);
2403 for (
size_t iii = 0; iii < tree.size(); ++iii )
2405 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2406 const Loc_tp l = root[iii].locator;
2407 KJB(
ASSERT( l < location_list.size() ));
2408 location_list.at( l ) = root + iii;
2410 location_list[ root[iii].locator ] = root + iii;
2416 root = recursive_copy( tree.root, tree );
2419 catch (std::bad_alloc& e)
2432 : m_nil( 0,
Sat_tp(), true, 00, 00, 00 ),
2450 if ( dictionary_is_small_linear_array() )
2456 recursive_destroy( root );
2460 location_list.clear();
2461 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2462 free_locator_list.clear();
2469 : m_nil( 0,
Sat_tp(), true, 00, 00, 00 ),
2472 copy_tree_into_empty( tree );
2485 if (
this != &tree )
2488 copy_tree_into_empty( tree );
2511 root =
new Node[ TREE_THRESH ];
2514 if (
size() < TREE_THRESH )
2516 return LOCATOR_BASE + linear_insert( key, sat );
2518 return LOCATOR_BASE + tree_insert( key, sat );
2533 os <<
"tree is empty\n";
2535 else if ( dictionary_is_small_linear_array() )
2537 os <<
"tiny tree is in an unsorted array, root=" << root <<
'\n';
2538 for (
size_t iii = 0; iii <
size(); ++iii )
2540 KJB(
ASSERT( are_both_children_nil( root + iii ) ));
2541 recursive_db_print( root + iii, 0, os );
2546 os <<
"Big tree with nil at " << & m_nil
2547 <<
", root=" << root <<
'\n';
2548 recursive_db_print( root, 0, os );
2550 db_print_locators();
2562 if ( m_nil.is_red() )
2564 return fail(
"nil is red" );
2569 return fail(
"nil points to a parent" );
2572 if ( ! locators_valid_in_nlogn_time() )
2574 return fail(
"locators are bad" );
2577 if ( dictionary_is_small_linear_array() )
2582 if ( blackheight_in_linear_time() == BLACKHEIGHT_BAD
2584 || red_node_has_red_child_in_linear_time()
2586 || ! sums_are_close_enough_in_linear_time( root )
2587 || ! is_bst_in_linear_time()
2590 return fail(
"tree structure is bad" );
2616 if ( dictionary_is_small_linear_array() )
2618 is_found = linear_search( key, sat_out, loc_out, 00 );
2622 is_found = tree_search( key, sat_out, root, loc_out );
2626 if ( is_found && loc_out )
2628 *loc_out += LOCATOR_BASE;
2662 if ( dictionary_is_small_linear_array() )
2665 if ( ! linear_search( query_key, sat_out, 00, & index ) )
2669 return del_array_elt( index );
2673 Node* ppp = tree_search( query_key, sat_out, root, 00 );
2680 return del_tree_node( ppp );
2697 if ( query_loc < LOCATOR_BASE )
2701 query_loc -= LOCATOR_BASE;
2703 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2704 if ( location_list.size() <= query_loc )
2709 const Node* ppp = location_list.at( query_loc );
2715 LLCI i = location_list.find(query_loc);
2716 if (location_list.end() ==
i)
return false;
2717 const Node*
const ppp = i -> second;
2719 KJB(
ASSERT( ppp -> locator == query_loc ));
2723 *key_out = ppp -> key;
2727 *sat_out = ppp -> sat;
2742 KJB(
ASSERT( LOCATOR_BASE <= query_loc ));
2743 query_loc -= LOCATOR_BASE;
2745 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2746 if ( location_list.size() <= query_loc )
2751 LLCI i = location_list.find(query_loc);
2752 if (location_list.end() ==
i)
return false;
2755 Node* ppp = location_list[ query_loc ];
2760 KJB(
ASSERT( ppp -> locator == query_loc ));
2763 if ( dictionary_is_small_linear_array() )
2765 if ( ppp < root || root +
size() <= ppp )
2769 KJB(
ASSERT( loc_list_good_here( ppp ) ));
2770 return del_array_elt( ppp - root );
2774 return del_tree_node( ppp );
2782 return loc_extremum( & Node::left, & std::min_element< const Node* > );
2789 return loc_extremum( & Node::right, & std::max_element< const Node* >);
2813 if ( query_loc < LOCATOR_BASE )
2818 query_loc -= LOCATOR_BASE;
2820 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2821 if ( location_list.size() <= query_loc )
2826 Node*
const ppp = location_list[ query_loc ];
2832 LLCI i = location_list.find(query_loc);
2833 if (location_list.end() ==
i)
return false;
2834 Node*
const ppp = i -> second;
2836 KJB(
ASSERT( ppp -> locator == query_loc ));
2839 if ( dictionary_is_small_linear_array() )
2841 if ( ppp < root || root +
size() <= ppp )
2845 ppp -> key = newkey;
2851 Loc_tp newloc =
insert( newkey, ppp -> sat ) - LOCATOR_BASE;
2852 Node*
const qqq = location_list[ newloc ];
2853 KJB(
ASSERT( qqq -> locator == newloc ));
2856 std::swap( location_list[ query_loc ], location_list[ newloc ] );
2857 std::swap( ppp -> locator, qqq -> locator );
2858 KJB(
ASSERT( loc_list_good_here( ppp ) ));
2859 KJB(
ASSERT( ppp == location_list[ newloc ] ));
2862 bool ok = del_tree_node( ppp );
2864 KJB(
ASSERT( newkey == location_list[ query_loc ] -> key ));
2891 if ( dictionary_is_small_linear_array() )
2935 if ( dictionary_is_small_linear_array() )
2937 return LOCATOR_BASE + array_seek_cukes( cumulative_keysum );
2939 return LOCATOR_BASE + tree_seek_cukes( root, cumulative_keysum );
2963 :
public std::iterator< std::bidirectional_iterator_tag, Loc_tp >
2965 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
2982 while ( m_index < m_tree -> location_list.size()
2983 && 00 == m_tree -> location_list[m_index]
2997 while ( 0 < m_index && 00 == m_tree -> location_list[m_index] )
3001 if (0 == m_index) advance_();
3009 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
3023 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
3024 const Node* n = m_tree -> location_list[m_index];
3025 KJB(
ASSERT(n && n -> locator == m_index));
3026 return LOCATOR_BASE + m_index;
3029 KJB(
ASSERT(m_it -> second -> locator == m_it -> first));
3030 return LOCATOR_BASE + m_it -> first;
3036 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
3037 return m_index == i.m_index && m_tree == i.m_tree;
3039 return m_it == i.m_it;
3050 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
3066 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
3084 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
3093 #if REDBLACK_H_2014_NOV_13_LOCATION_LIST_IMPL_USES_ARRAY
3114 location_list.swap(other.location_list);
3115 free_locator_list.swap(other.free_locator_list);
3130 template <
typename S>
bool operator!=(const const_iterator &i) const
Definition: redblack.h:3043
interface for priority queues used by Dijkstra's algorithm
Int_matrix::Value_type max(const Int_matrix &mat)
Return the maximum value in this matrix.
Definition: l_int_matrix.h:1397
double accumulate(const Matrix_d< R, C, T > &mat, double init)
Definition: m_matrix_d.impl.h:432
Loc_tp loc_min() const
return the locator for the record with the minimum key, or 0
Definition: redblack.h:2780
size_t size() const
return the number of key+value pairs in the dictionary.
Definition: redblack.h:2794
const_iterator & operator--()
Definition: redblack.h:3064
#define KJB(x)
Definition: l_util.h:9
void swap(Perspective_camera &cam1, Perspective_camera &cam2)
Swap two cameras.
Definition: perspective_camera.h:599
Loc_tp operator*() const
Definition: redblack.h:3021
bool operator==(const const_iterator &i) const
Definition: redblack.h:3034
bool access_loc(Loc_tp query_loc, Key_tp *key_out, Sat_tp *sat_out) const
access a record via its locator, a constant-time operation.
Definition: redblack.h:2695
#define ASSERT(condition, message)
Definition: Assert.h:45
const_iterator operator++(int)
Definition: redblack.h:3058
bool tree_valid_in_nlogn_time() const
scan dictionary in linear time to verify invariants are valid
Definition: redblack.h:2558
const_iterator end() const
Definition: redblack.h:3091
#define NTX(a)
Definition: l_exception.h:89
bool erase_loc(Loc_tp query_loc)
remove the record indicated by query_loc, or return false if bad
Definition: redblack.h:2740
Redblack_subtree_sum()
default ctor
Definition: redblack.h:2431
bool erase_key(const Key_tp &query_key, Sat_tp *sat_out)
erase a key+value pair from the dictionary
Definition: redblack.h:2657
pure virtual interface for priority queue in Dijkstra's algorithm
Definition: diprique.h:72
Loc_tp ins_max_key(const Sat_tp &sat)
the following is a hack to mimic StochasticPriorityQueue
Definition: redblack.h:2522
function straight edges straight lines(nlines,[x1 x2 y1 y2 theta r])%%To display result ss
Definition: APPgetLargeConnectedEdges.m:20
bool rekey_loc(Loc_tp query_loc, const Key_tp &newkey)
change the key value for a node to a new value, O(log n) time
Definition: redblack.h:2808
void debug_print(std::ostream &) const
stub: remove print code when not checking aggressively
Definition: redblack.h:2554
const Vector3 BLACK(0.0, 0.0, 0.0)
Definition: gr_opengl_color.h:33
Loc_tp loc_max() const
return the locator for the record with the maximum key, or 0
Definition: redblack.h:2787
a balanced binary search tree storing subtree sums in each node.
Definition: redblack.h:165
Loc_tp loc_using_cumulative_key_sum(Key_tp cumulative_keysum) const
fetch a node based on inorder cumulative sum of tree keys
Definition: redblack.h:2929
Redblack_subtree_sum(const Redblack_subtree_sum< SATELLITE_TYPE > &tree)
copy ctor (same locators will work in this one too)
Definition: redblack.h:2468
Loc_tp Dijkstra_extraction() const
hack proxy to make this and a stochastic pri queue work alike
Definition: redblack.h:2943
const_iterator & operator++()
Definition: redblack.h:3048
const_iterator begin() const
Definition: redblack.h:3082
bool find_key(const Key_tp &key, Sat_tp *sat_out, Loc_tp *loc_out)
search for a key in the dictionary; return first one.
Definition: redblack.h:2613
void clear()
destroy the tree or the linear array.
Definition: redblack.h:2442
friend class const_iterator
Definition: redblack.h:2959
float Key_tp
type that we use for keys
Definition: diprique.h:75
DijkstraPriorityQueue< SATELLITE_TYPE >::Key_tp Key_tp
Definition: redblack.h:170
count
Definition: APPgetLargeConnectedEdges.m:71
void swap(kjb::Gsl_Multimin_fdf &m1, kjb::Gsl_Multimin_fdf &m2)
Swap two wrapped multimin objects.
Definition: gsl_multimin.h:693
sum(zmx.*zmy) sum(zmy.^2)]
#define dest(triedge, pointptr)
Definition: triangle.c:938
SATELLITE_TYPE Sat_tp
Definition: redblack.h:169
Loc_tp insert(const Key_tp &key, const Sat_tp &sat)
insert a new key+value pair in the dictionary
Definition: redblack.h:2506
Redblack_subtree_sum & operator=(const Redblack_subtree_sum< SATELLITE_TYPE > &tree)
assignment operator (same locators will work in this one too)
Definition: redblack.h:2481
Int_matrix::Value_type min(const Int_matrix &mat)
Return the minimum value in this matrix.
Definition: l_int_matrix.h:1385
bool is_empty() const
return whether the size is zero
Definition: redblack.h:2801
size_t Loc_tp
type that we use for locators
Definition: diprique.h:76
iterator class for a tree – lets you access node locators.
Definition: redblack.h:2962
bool operator<(const RatPoint &a, const RatPoint &b)
"row-major" ordering of points
Definition: ratpoint.h:82
const_iterator(size_t ix, const Redblack_subtree_sum< Sat_tp > *t)
Definition: redblack.h:3010
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
~Redblack_subtree_sum()
dtor clears the structure
Definition: redblack.h:2495
DijkstraPriorityQueue< SATELLITE_TYPE >::Loc_tp Loc_tp
Definition: redblack.h:171
SatLoc Sat_tp
type of satellite data
Definition: diprique.h:74
const_iterator operator--(int)
Definition: redblack.h:3074
Key_tp root_sum() const
return subtree sum at root node (i.e., the sum of all keys).
Definition: redblack.h:2885