📄 tree.hh
字号:
} else { position.node->parent->last_child=position.node->last_child; } position.node->next_sibling=position.node->first_child; position.node->next_sibling->prev_sibling=position.node; position.node->first_child=0; position.node->last_child=0; return position; }template <class T, class tree_node_allocator>template <typename iter>iter tree<T, tree_node_allocator>::reparent(iter position, sibling_iterator begin, sibling_iterator end) { tree_node *first=begin.node; tree_node *last=first; assert(first!=position.node); if(begin==end) return begin; // determine last node while((++begin)!=end) { last=last->next_sibling; } // move subtree if(first->prev_sibling==0) { first->parent->first_child=last->next_sibling; } else { first->prev_sibling->next_sibling=last->next_sibling; } if(last->next_sibling==0) { last->parent->last_child=first->prev_sibling; } else { last->next_sibling->prev_sibling=first->prev_sibling; } if(position.node->first_child==0) { position.node->first_child=first; position.node->last_child=last; first->prev_sibling=0; } else { position.node->last_child->next_sibling=first; first->prev_sibling=position.node->last_child; position.node->last_child=last; } last->next_sibling=0; tree_node *pos=first; while(1==1) { pos->parent=position.node; if(pos==last) break; pos=pos->next_sibling; } return first; }template <class T, class tree_node_allocator>template <typename iter> iter tree<T, tree_node_allocator>::reparent(iter position, iter from) { if(from.node->first_child==0) return position; return reparent(position, from.node->first_child, end(from)); }template <class T, class tree_node_allocator>template <typename iter> iter tree<T, tree_node_allocator>::wrap(iter position, const T& x) { assert(position.node!=0); sibling_iterator fr=position, to=position; ++to; iter ret = insert(position, x); reparent(ret, fr, to); return ret; }template <class T, class tree_node_allocator>template <typename iter> iter tree<T, tree_node_allocator>::move_after(iter target, iter source) { tree_node *dst=target.node; tree_node *src=source.node; assert(dst); assert(src); if(dst==src) return source; if(dst->next_sibling) if(dst->next_sibling==src) // already in the right spot return source; // take src out of the tree if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; else src->parent->first_child=src->next_sibling; if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; else src->parent->last_child=src->prev_sibling; // connect it to the new point if(dst->next_sibling!=0) dst->next_sibling->prev_sibling=src; else dst->parent->last_child=src; src->next_sibling=dst->next_sibling; dst->next_sibling=src; src->prev_sibling=dst; src->parent=dst->parent; return src; }template <class T, class tree_node_allocator>template <typename iter> iter tree<T, tree_node_allocator>::move_before(iter target, iter source) { tree_node *dst=target.node; tree_node *src=source.node; assert(dst); assert(src); if(dst==src) return source; if(dst->prev_sibling) if(dst->prev_sibling==src) // already in the right spot return source; // take src out of the tree if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; else src->parent->first_child=src->next_sibling; if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; else src->parent->last_child=src->prev_sibling; // connect it to the new point if(dst->prev_sibling!=0) dst->prev_sibling->next_sibling=src; else dst->parent->first_child=src; src->prev_sibling=dst->prev_sibling; dst->prev_sibling=src; src->next_sibling=dst; src->parent=dst->parent; return src; }// specialisation for sibling_iteratorstemplate <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::move_before(sibling_iterator target, sibling_iterator source) { tree_node *dst=target.node; tree_node *src=source.node; tree_node *dst_prev_sibling; if(dst==0) { // must then be an end iterator dst_prev_sibling=target.parent_->last_child; assert(dst_prev_sibling); } else dst_prev_sibling=dst->prev_sibling; assert(src); if(dst==src) return source; if(dst_prev_sibling) if(dst_prev_sibling==src) // already in the right spot return source; // take src out of the tree if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; else src->parent->first_child=src->next_sibling; if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; else src->parent->last_child=src->prev_sibling; // connect it to the new point if(dst_prev_sibling!=0) dst_prev_sibling->next_sibling=src; else target.parent_->first_child=src; src->prev_sibling=dst_prev_sibling; if(dst) { dst->prev_sibling=src; src->parent=dst->parent; } src->next_sibling=dst; return src; }template <class T, class tree_node_allocator>template <typename iter> iter tree<T, tree_node_allocator>::move_ontop(iter target, iter source) { tree_node *dst=target.node; tree_node *src=source.node; assert(dst); assert(src); if(dst==src) return source; // remember connection points tree_node *b_prev_sibling=dst->prev_sibling; tree_node *b_next_sibling=dst->next_sibling; tree_node *b_parent=dst->parent; // remove target erase(target); // take src out of the tree if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; else src->parent->first_child=src->next_sibling; if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; else src->parent->last_child=src->prev_sibling; // connect it to the new point if(b_prev_sibling!=0) b_prev_sibling->next_sibling=src; else b_parent->first_child=src; if(b_next_sibling!=0) b_next_sibling->prev_sibling=src; else b_parent->last_child=src; src->prev_sibling=b_prev_sibling; src->next_sibling=b_next_sibling; src->parent=b_parent; return src; }template <class T, class tree_node_allocator>void tree<T, tree_node_allocator>::merge(sibling_iterator to1, sibling_iterator to2, sibling_iterator from1, sibling_iterator from2, bool duplicate_leaves) { sibling_iterator fnd; while(from1!=from2) { if((fnd=std::find(to1, to2, (*from1))) != to2) { // element found if(from1.begin()==from1.end()) { // full depth reached if(duplicate_leaves) append_child(parent(to1), (*from1)); } else { // descend further merge(fnd.begin(), fnd.end(), from1.begin(), from1.end(), duplicate_leaves); } } else { // element missing insert_subtree(to2, from1); } ++from1; } }template <class T, class tree_node_allocator>void tree<T, tree_node_allocator>::sort(sibling_iterator from, sibling_iterator to, bool deep) { std::less<T> comp; sort(from, to, comp, deep); }template <class T, class tree_node_allocator>template <class StrictWeakOrdering>void tree<T, tree_node_allocator>::sort(sibling_iterator from, sibling_iterator to, StrictWeakOrdering comp, bool deep) { if(from==to) return; // make list of sorted nodes // CHECK: if multiset stores equivalent nodes in the order in which they // are inserted, then this routine should be called 'stable_sort'. std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> > nodes(comp); sibling_iterator it=from, it2=to; while(it != to) { nodes.insert(it.node); ++it; } // reassemble --it2; // prev and next are the nodes before and after the sorted range tree_node *prev=from.node->prev_sibling; tree_node *next=it2.node->next_sibling; typename std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> >::iterator nit=nodes.begin(), eit=nodes.end(); if(prev==0) { if((*nit)->parent!=0) // to catch "sorting the head" situations, when there is no parent (*nit)->parent->first_child=(*nit); } else prev->next_sibling=(*nit); --eit; while(nit!=eit) { (*nit)->prev_sibling=prev; if(prev) prev->next_sibling=(*nit); prev=(*nit); ++nit; } // prev now points to the last-but-one node in the sorted range if(prev) prev->next_sibling=(*eit); // eit points to the last node in the sorted range. (*eit)->next_sibling=next; (*eit)->prev_sibling=prev; // missed in the loop above if(next==0) { if((*eit)->parent!=0) // to catch "sorting the head" situations, when there is no parent (*eit)->parent->last_child=(*eit); } else next->prev_sibling=(*eit); if(deep) { // sort the children of each node too sibling_iterator bcs(*nodes.begin()); sibling_iterator ecs(*eit); ++ecs; while(bcs!=ecs) { sort(begin(bcs), end(bcs), comp, deep); ++bcs; } } }template <class T, class tree_node_allocator>template <typename iter>bool tree<T, tree_node_allocator>::equal(const iter& one_, const iter& two, const iter& three_) const { std::equal_to<T> comp; return equal(one_, two, three_, comp); }template <class T, class tree_node_allocator>template <typename iter>bool tree<T, tree_node_allocator>::equal_subtree(const iter& one_, const iter& two_) const { std::equal_to<T> comp; return equal_subtree(one_, two_, comp); }template <class T, class tree_node_allocator>template <typename iter, class BinaryPredicate>bool tree<T, tree_node_allocator>::equal(const iter& one_, const iter& two, const iter& three_, BinaryPredicate fun) const { pre_order_iterator one(one_), three(three_);// if(one==two && is_valid(three) && three.number_of_children()!=0)// return false; while(one!=two && is_valid(three)) { if(!fun(*one,*three)) return false; if(one.number_of_children()!=three.number_of_children()) return false; ++one; ++three; } return true; }template <class T, class tree_node_allocator>template <typename iter, class BinaryPredicate>bool tree<T, tree_node_allocator>::equal_subtree(const iter& one_, const iter& two_, BinaryPredicate fun) const { pre_order_iterator one(one_), two(two_); if(!fun(*one,*two)) return false; if(number_of_children(one)!=number_of_children(two)) return false; return equal(begin(one),end(one),begin(two),fun); }template <class T, class tree_node_allocator>tree<T, tree_node_allocator> tree<T, tree_node_allocator>::subtree(sibling_iterator from, sibling_iterator to) const { tree tmp; tmp.set_head(value_type()); tmp.replace(tmp.begin(), tmp.end(), from, to); return tmp; }template <class T, class tree_node_allocator>void tree<T, tree_node_allocator>::subtree(tree& tmp, sibling_iterator from, sibling_iterator to) const { tmp.set_head(value_type()); tmp.replace(tmp.begin(), tmp.end(), from, to); }template <class T, class tree_node_allocator>int tree<T, tree_node_allocator>::size() const { int i=0; pre_order_iterator it=begin(), eit=end(); while(it!=eit) { ++i; ++it; } return i; }template <class T, class tree_node_allocator>bool tree<T, tree_node_allocator>::empty() const { pre_order_iterator it=begin(), eit=end(); return (it==eit); }template <class T, class tree_node_allocator>int tree<T, tree_node_allocator>::depth(const iterator_base& it) const { tree_node* pos=it.node; assert(pos!=0); int ret=0; while(pos->parent!=0) { pos=pos->parent; ++ret; } return ret; }template <class T, class tree_node_allocator>unsigned int tree<T, tree_node_allocator>::number_of_children(const iterator_base& it) { tree_node *pos=it.node->first_child;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -