check integrity of tree. fix bug regarding updating

This commit is contained in:
Maximilian Keßler 2022-04-17 13:57:09 +02:00
parent ca3750e6d7
commit 61f468c150
2 changed files with 31 additions and 9 deletions

View File

@ -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);
}
}
} }
} }

View File

@ -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);