📄 tree.hh
字号:
int size() const; /// Check if tree is empty. bool empty() const; /// Compute the depth to the root. int depth(const iterator_base&) const; /// Count the number of children of node at position. static unsigned int number_of_children(const iterator_base&); /// Count the number of 'next' siblings of node at iterator. unsigned int number_of_siblings(const iterator_base&) const; /// Determine whether node at position is in the subtrees with root in the range. bool is_in_subtree(const iterator_base& position, const iterator_base& begin, const iterator_base& end) const; /// Determine whether the iterator is an 'end' iterator and thus not actually pointing to a node. bool is_valid(const iterator_base&) const; /// Determine the index of a node in the range of siblings to which it belongs. unsigned int index(sibling_iterator it) const; /// Inverse of 'index': return the n-th child of the node at position. sibling_iterator child(const iterator_base& position, unsigned int) const; /// Comparator class for iterators (compares pointer values; why doesn't this work automatically?) class iterator_base_less { public: bool operator()(const typename tree<T, tree_node_allocator>::iterator_base& one, const typename tree<T, tree_node_allocator>::iterator_base& two) const { return one.node < two.node; } }; tree_node *head, *feet; // head/feet are always dummy; if an iterator points to them it is invalid private: tree_node_allocator alloc_; void head_initialise_(); void copy_(const tree<T, tree_node_allocator>& other); /// Comparator class for two nodes of a tree (used for sorting and searching). template<class StrictWeakOrdering> class compare_nodes { public: compare_nodes(StrictWeakOrdering comp) : comp_(comp) {}; bool operator()(const tree_node *a, const tree_node *b) { static StrictWeakOrdering comp; return comp(a->data, b->data); } private: StrictWeakOrdering comp_; };};//template <class T, class tree_node_allocator>//class iterator_base_less {// public:// bool operator()(const typename tree<T, tree_node_allocator>::iterator_base& one,// const typename tree<T, tree_node_allocator>::iterator_base& two) const// {// txtout << "operatorclass<" << one.node < two.node << std::endl;// return one.node < two.node;// }//};// template <class T, class tree_node_allocator>// bool operator<(const typename tree<T, tree_node_allocator>::iterator& one,// const typename tree<T, tree_node_allocator>::iterator& two)// {// txtout << "operator< " << one.node < two.node << std::endl;// if(one.node < two.node) return true;// return false;// }// // template <class T, class tree_node_allocator>// bool operator==(const typename tree<T, tree_node_allocator>::iterator& one,// const typename tree<T, tree_node_allocator>::iterator& two)// {// txtout << "operator== " << one.node == two.node << std::endl;// if(one.node == two.node) return true;// return false;// }// // template <class T, class tree_node_allocator>// bool operator>(const typename tree<T, tree_node_allocator>::iterator_base& one,// const typename tree<T, tree_node_allocator>::iterator_base& two)// {// txtout << "operator> " << one.node < two.node << std::endl;// if(one.node > two.node) return true;// return false;// }// Treetemplate <class T, class tree_node_allocator>tree<T, tree_node_allocator>::tree() { head_initialise_(); }template <class T, class tree_node_allocator>tree<T, tree_node_allocator>::tree(const T& x) { head_initialise_(); set_head(x); }template <class T, class tree_node_allocator>tree<T, tree_node_allocator>::tree(const iterator_base& other) { head_initialise_(); set_head((*other)); replace(begin(), other); }template <class T, class tree_node_allocator>tree<T, tree_node_allocator>::~tree() { clear(); alloc_.deallocate(head,1); alloc_.deallocate(feet,1); }template <class T, class tree_node_allocator>void tree<T, tree_node_allocator>::head_initialise_() { head = alloc_.allocate(1,0); // MSVC does not have default second argument feet = alloc_.allocate(1,0); head->parent=0; head->first_child=0; head->last_child=0; head->prev_sibling=0; //head; head->next_sibling=feet; //head; feet->parent=0; feet->first_child=0; feet->last_child=0; feet->prev_sibling=head; feet->next_sibling=0; }template <class T, class tree_node_allocator>void tree<T, tree_node_allocator>::operator=(const tree<T, tree_node_allocator>& other) { copy_(other); }template <class T, class tree_node_allocator>tree<T, tree_node_allocator>::tree(const tree<T, tree_node_allocator>& other) { head_initialise_(); copy_(other); }template <class T, class tree_node_allocator>void tree<T, tree_node_allocator>::copy_(const tree<T, tree_node_allocator>& other) { clear(); pre_order_iterator it=other.begin(), to=begin(); while(it!=other.end()) { to=insert(to, (*it)); it.skip_children(); ++it; } to=begin(); it=other.begin(); while(it!=other.end()) { to=replace(to, it); to.skip_children(); it.skip_children(); ++to; ++it; } }template <class T, class tree_node_allocator>void tree<T, tree_node_allocator>::clear() { if(head) while(head->next_sibling!=feet) erase(pre_order_iterator(head->next_sibling)); }template<class T, class tree_node_allocator> void tree<T, tree_node_allocator>::erase_children(const iterator_base& it) { tree_node *cur=it.node->first_child; tree_node *prev=0; while(cur!=0) { prev=cur; cur=cur->next_sibling; erase_children(pre_order_iterator(prev)); kp::destructor(&prev->data); alloc_.deallocate(prev,1); } it.node->first_child=0; it.node->last_child=0; }template<class T, class tree_node_allocator> template<class iter>iter tree<T, tree_node_allocator>::erase(iter it) { tree_node *cur=it.node; assert(cur!=head); iter ret=it; ret.skip_children(); ++ret; erase_children(it); if(cur->prev_sibling==0) { cur->parent->first_child=cur->next_sibling; } else { cur->prev_sibling->next_sibling=cur->next_sibling; } if(cur->next_sibling==0) { cur->parent->last_child=cur->prev_sibling; } else { cur->next_sibling->prev_sibling=cur->prev_sibling; } kp::destructor(&cur->data); alloc_.deallocate(cur,1); return ret; }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::begin() const { return pre_order_iterator(head->next_sibling); }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::end() const { return pre_order_iterator(feet); }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::breadth_first_queued_iterator tree<T, tree_node_allocator>::begin_breadth_first() const { return breadth_first_queued_iterator(head->next_sibling); }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::breadth_first_queued_iterator tree<T, tree_node_allocator>::end_breadth_first() const { return breadth_first_queued_iterator(); }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::begin_post() const { tree_node *tmp=head->next_sibling; if(tmp!=feet) { while(tmp->first_child) tmp=tmp->first_child; } return post_order_iterator(tmp); }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::end_post() const { return post_order_iterator(feet); }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::begin_fixed(const iterator_base& pos, unsigned int dp) const { tree_node *tmp=pos.node; unsigned int curdepth=0; while(curdepth<dp) { // go down one level while(tmp->first_child==0) { tmp=tmp->next_sibling; if(tmp==0) throw std::range_error("tree: begin_fixed out of range"); } tmp=tmp->first_child; ++curdepth; } return tmp; }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::end_fixed(const iterator_base& pos, unsigned int dp) const { assert(1==0); // FIXME: not correct yet tree_node *tmp=pos.node; unsigned int curdepth=1; while(curdepth<dp) { // go down one level while(tmp->first_child==0) { tmp=tmp->next_sibling; if(tmp==0) throw std::range_error("tree: end_fixed out of range"); } tmp=tmp->first_child; ++curdepth; } return tmp; }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::begin(const iterator_base& pos) const { assert(pos.node!=0); if(pos.node->first_child==0) { return end(pos); } return pos.node->first_child; }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::end(const iterator_base& pos) const { sibling_iterator ret(0); ret.parent_=pos.node; return ret; }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::leaf_iterator tree<T, tree_node_allocator>::begin_leaf() const { tree_node *tmp=head->next_sibling; if(tmp!=feet) { while(tmp->first_child) tmp=tmp->first_child; } return leaf_iterator(tmp); }template <class T, class tree_node_allocator>typename tree<T, tree_node_allocator>::leaf_iterator tree<T, tree_node_allocator>::end_leaf() const { return leaf_iterator(feet); }template <class T, class tree_node_allocator>template <typename iter>iter tree<T, tree_node_allocator>::parent(iter position) { assert(position.node!=0); return iter(position.node->parent); }template <class T, class tree_node_allocator>template <typename iter>iter tree<T, tree_node_allocator>::previous_sibling(iter position) const { assert(position.node!=0); iter ret(position); ret.node=position.node->prev_sibling; return ret; }template <class T, class tree_node_allocator>template <typename iter>iter tree<T, tree_node_allocator>::next_sibling(iter position) const { assert(position.node!=0); iter ret(position); ret.node=position.node->next_sibling; return ret; }template <class T, class tree_node_allocator>template <typename iter>iter tree<T, tree_node_allocator>::next_at_same_depth(iter position) const { assert(position.node!=0); iter ret(position); if(position.node->next_sibling) { ret.node=position.node->next_sibling; } else { int relative_depth=0; upper: do { ret.node=ret.node->parent; if(ret.node==0) return ret; --relative_depth; } while(ret.node->next_sibling==0); lower: ret.node=ret.node->next_sibling; while(ret.node->first_child==0) { if(ret.node->next_sibling==0) goto upper; ret.node=ret.node->next_sibling; if(ret.node==0) return ret; } while(relative_depth<0 && ret.node->first_child!=0) { ret.node=ret.node->first_child; ++relative_depth; } if(relative_depth<0) { if(ret.node->next_sibling==0) goto upper; else goto lower;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -