Advertisement
Guest User

Untitled

a guest
May 21st, 2012
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.28 KB | None | 0 0
  1. // Двусторонний итератор для чтения вершин в симметричном порядке.
  2.     class ConstIterator {
  3.       typedef TNode Node;
  4.       friend class Treap<Node>;
  5.       public:
  6.         typedef ::std::bidirectional_iterator_tag iterator_category;
  7.         typedef ptrdiff_t difference_type;
  8.         typedef Node value_type;
  9.         typedef const Node& reference;
  10.         typedef const Node* pointer;
  11.  
  12.         // Не использовать, только для объявления переменных и для STL!
  13.         ConstIterator()
  14.           : node_(NULL),
  15.             first_node_(NULL),
  16.             last_node_(NULL) {}
  17.  
  18.         ConstIterator(const ConstIterator& rhv)
  19.           : node_(rhv.node_),
  20.             first_node_(rhv.first_node_),
  21.             last_node_(rhv.last_node_) {
  22.             FAST_CHECK(!node_ || (first_node_ && last_node_));
  23.         }
  24.  
  25.         ConstIterator& operator=(const ConstIterator& rhv) {
  26.             ConstIterator(rhv).swap(*this);
  27.             return *this;
  28.         }
  29.  
  30.         void swap(ConstIterator& rhv) {
  31.             ::std::swap(this->node_, rhv.node_);
  32.             ::std::swap(this->first_node_, rhv.first_node_);
  33.             ::std::swap(this->last_node_, rhv.last_node_);
  34.         }
  35.  
  36.         bool operator==(const ConstIterator& rhv) const {
  37.             if ( last_node_ && rhv.last_node_ ) {
  38.                 // Сравнение итераторов разных деревьев.
  39.                 FAST_CHECK(first_node_ == rhv.first_node_ &&
  40.                            last_node_ == rhv.last_node_);
  41.             }
  42.  
  43.             // Отдельная проверка на is_end_ нужна для сравнения с end().
  44.             if ( this->at_end() && rhv.at_end() ) {
  45.                 return true;
  46.             }
  47.  
  48.             if ( this->node_ == rhv.node_ ) {
  49.                 // Если вылетает этот CHECK, значит, итераторы по меньшей мере
  50.                 // инвалидированы, так как указывают на одну вершину двух
  51.                 // разных деревьев.
  52.                 FAST_CHECK(this->first_node_ == rhv.first_node_ &&
  53.                        this->last_node_ == rhv.last_node_);
  54.                 return true;
  55.             }
  56.  
  57.             return false;
  58.         }
  59.         bool operator!=(const ConstIterator& rhv) const {
  60.             return !( *this == rhv );
  61.         }
  62.  
  63.         // @pre !at_end().
  64.         ConstIterator& operator++() {
  65.             FAST_CHECK(!at_end());
  66.             if ( node_->right_child() ) {
  67.                 node_ = node_->right_child();
  68.                 GoDownByLeftChildrenToTheNodeWithNoLeftChild();
  69.  
  70.             } else {
  71.                 GoUpToParentForWhichCurrentNodeIsLeftChild();
  72.             }
  73.             return *this;
  74.         }
  75.         // @pre !at_end().
  76.         ConstIterator operator++(int) {
  77.             ConstIterator tmp(*this);
  78.             ++(*this);
  79.             return tmp;
  80.         }
  81.  
  82.         // @pre at_begin().
  83.         ConstIterator& operator--() {
  84.             FAST_CHECK(!at_begin());
  85.  
  86.             // Итератор указывал за последний элемент, а теперь на него.
  87.             if ( at_end() ) {
  88.                 // Это должно быть непустое дерево.
  89.                 FAST_CHECK(last_node_ != NULL && first_node_ != NULL);
  90.                 node_ = last_node_;
  91.                 return *this;
  92.             }
  93.  
  94.             if ( node_->left_child() ) {
  95.                 node_ = node_->left_child();
  96.                 GoDownByRightChildrenToTheNodeWithNoRightChild();
  97.  
  98.             } else {
  99.                 GoUpToParentForWhichCurrentNodeIsRightChild();
  100.             }
  101.             return *this;
  102.         }
  103.         // @pre !at_begin().
  104.         ConstIterator operator--(int) {
  105.             ConstIterator tmp(*this);
  106.             --(*this);
  107.             return tmp;
  108.         }
  109.  
  110.         // @pre !at_end().
  111.         reference operator*() const {
  112.             FAST_CHECK(!at_end());
  113.             return *node_;
  114.         }
  115.         // @pre !at_end().
  116.         pointer operator->() const {
  117.             FAST_CHECK(!at_end());
  118.             return node_;
  119.         }
  120.  
  121.         bool at_begin() const {
  122.             return node_ != NULL && node_ == first_node_;
  123.         }
  124.         bool at_end() const {
  125.             return node_ == NULL;
  126.         }
  127.  
  128.         const Node* node() const {
  129.             return node_;
  130.         }
  131.  
  132.       private:
  133.         // node — текущий элемент. Может быть NULL, тогда это end-итератор.
  134.         // first_node — указатель на первый элемент (наименьший).
  135.         // last_node — указатель на последний элемент (наибольший).
  136.         // Если first_node == NULL && last_node == NULL — дерево пустое.
  137.         // Асимптотическая сложность: O(1).
  138.         // Дополнительная память: O(1).
  139.         ConstIterator(const Node* node,
  140.                       const Node* first_node, const Node* last_node)
  141.           : node_(node),
  142.             first_node_(first_node),
  143.             last_node_(last_node) {
  144.             if ( node_ ) {
  145.                 FAST_CHECK(first_node_ && last_node_);
  146.             } else {
  147.                 FAST_CHECK(at_end() && !at_begin());
  148.                 FAST_CHECK(!!first_node_ == !!last_node_);  // оба NULL или нет.
  149.             }
  150.         }
  151.  
  152.  
  153.         void GoDownByLeftChildrenToTheNodeWithNoLeftChild() {
  154.             while ( node_->left_child() ) {
  155.                 node_ = node_->left_child();
  156.             }
  157.         }
  158.         void GoDownByRightChildrenToTheNodeWithNoRightChild() {
  159.             while ( node_->right_child() ) {
  160.                 node_ = node_->right_child();
  161.             }
  162.         }
  163.  
  164.         void GoUpToParentForWhichCurrentNodeIsLeftChild() {
  165.             while ( node_->parent() && node_->parent()->right_child()==node_ ) {
  166.                 node_ = node_->parent();
  167.             }
  168.  
  169.             // Или parent == NULL — прошли самую последнюю вершину, конец.
  170.             // Или parent != NULL — следующий узел.
  171.             if ( node_->parent() ) {
  172.                 node_ = node_->parent();
  173.  
  174.             } else {
  175.                 GoDownByRightChildrenToTheNodeWithNoRightChild();
  176.                 FAST_CHECK(node_ == last_node_);
  177.                 node_ = NULL;
  178.                 FAST_CHECK(at_end());
  179.             }
  180.         }
  181.  
  182.         void GoUpToParentForWhichCurrentNodeIsRightChild() {
  183.             while ( node_->parent() && node_->parent()->left_child()==node_ ) {
  184.                 node_ = node_->parent();
  185.             }
  186.  
  187.             if ( node_->parent() ) {
  188.                 node_ = node_->parent();
  189.  
  190.             } else {
  191.                 // Вообще такого случая быть не должно, так как в operator--
  192.                 // стоит предусловие !at_begin().
  193.                 volatile bool f = false;
  194.                 (void)f;
  195.                 FAST_CHECK(f);
  196.             }
  197.         }
  198.  
  199.         const Node* node_;
  200.         const Node* first_node_;
  201.         const Node* last_node_;
  202.     };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement