check integrity of tree. fix bug regarding updating
This commit is contained in:
parent
ca3750e6d7
commit
61f468c150
2 changed files with 31 additions and 9 deletions
|
@ -35,8 +35,9 @@ SegmentTree::SegmentTree(const std::vector<RectCoord> &coords):
|
||||||
}
|
}
|
||||||
|
|
||||||
void SegmentTree::add_interval(Interval interval) {
|
void SegmentTree::add_interval(Interval interval) {
|
||||||
|
check_integrity();
|
||||||
std::stack<Index> visit_to;
|
std::stack<Index> visit_to;
|
||||||
std::vector<Index> update_to;
|
std::stack<Index> update_to;
|
||||||
visit_to.push(0);
|
visit_to.push(0);
|
||||||
while(!visit_to.empty()) {
|
while(!visit_to.empty()) {
|
||||||
Index node_idx = visit_to.top();
|
Index node_idx = visit_to.top();
|
||||||
|
@ -51,18 +52,21 @@ void SegmentTree::add_interval(Interval interval) {
|
||||||
visit_to.push(right_child_idx(node_idx));
|
visit_to.push(right_child_idx(node_idx));
|
||||||
}
|
}
|
||||||
if(!_nodes[node_idx].covered()) {
|
if(!_nodes[node_idx].covered()) {
|
||||||
update_to.push_back(node_idx);
|
update_to.push(node_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(auto update_idx : update_to) {
|
while(!update_to.empty()) {
|
||||||
update_covered_length(update_idx);
|
update_covered_length(update_to.top());
|
||||||
|
update_to.pop();
|
||||||
}
|
}
|
||||||
|
check_integrity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SegmentTree::remove_interval(Interval interval) {
|
void SegmentTree::remove_interval(Interval interval) {
|
||||||
|
check_integrity();
|
||||||
std::stack<Index> visit_to;
|
std::stack<Index> visit_to;
|
||||||
std::vector<Index> update_to;
|
std::stack<Index> update_to;
|
||||||
visit_to.push(0);
|
visit_to.push(0);
|
||||||
while(!visit_to.empty()) {
|
while(!visit_to.empty()) {
|
||||||
Index node_idx = visit_to.top();
|
Index node_idx = visit_to.top();
|
||||||
|
@ -77,11 +81,28 @@ void SegmentTree::remove_interval(Interval interval) {
|
||||||
visit_to.push(right_child_idx(node_idx));
|
visit_to.push(right_child_idx(node_idx));
|
||||||
}
|
}
|
||||||
if(!_nodes[node_idx].covered()) {
|
if(!_nodes[node_idx].covered()) {
|
||||||
update_to.push_back(node_idx);
|
update_to.push(node_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(auto update_idx : update_to) {
|
while(!update_to.empty()) {
|
||||||
update_covered_length(update_idx);
|
update_covered_length(update_to.top());
|
||||||
|
update_to.pop();
|
||||||
}
|
}
|
||||||
}
|
check_integrity();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SegmentTree::check_integrity() {
|
||||||
|
for(Index node_idx = 0 ; node_idx < _nodes.size(); ++node_idx) {
|
||||||
|
if(_nodes[node_idx].covered()) {
|
||||||
|
assert(_nodes[node_idx].covered_length == _nodes[node_idx].segment_length());
|
||||||
|
} else {
|
||||||
|
if(is_leaf(node_idx)) {
|
||||||
|
assert(_nodes[node_idx].covered_length == 0);
|
||||||
|
} else {
|
||||||
|
assert(_nodes[node_idx].covered_length == \
|
||||||
|
left_child(node_idx).covered_length + right_child(node_idx).covered_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
inline Unit length_covered_intervals();
|
inline Unit length_covered_intervals();
|
||||||
void add_interval(Interval interval);
|
void add_interval(Interval interval);
|
||||||
void remove_interval(Interval interval);
|
void remove_interval(Interval interval);
|
||||||
|
void check_integrity();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static Index left_child_idx(Index node_idx);
|
inline static Index left_child_idx(Index node_idx);
|
||||||
|
|
Loading…
Reference in a new issue