/* VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}" VIM: let b:cf5run="{OUT}" */ #include #include #include #include struct node { node * parent; node * left; node * right; int val; node(int v, node * p) : parent(p) , left(nullptr) , right(nullptr) , val(v) {} }; node * build_tree(const std::vector& t){ node * root = nullptr; bool left = true; for (int v : t){ if (v!=-1){ node * n = new node(v, root); if ( root ){ if ( left ){ root->left = n; } else { root->right = n; } } root = n; left = true; } else { if (!root){ break; } if (!left){ while ( root->parent && !left){ left = root->parent->left == root; root = root->parent; } if (!left){ break; } } left = false; } } return root; } void print(const node * root){ if ( !root ){ std::cout << "-1"; } else { std::cout << '('; print(root->left); std::cout << ',' << root->val << ','; print(root->right); std::cout << ')'; } } class tree_itor { node * n; public: tree_itor() : n(nullptr) {} tree_itor(node * _n) : n(leftmost(_n)) {} tree_itor& operator ++ () { if (n->right){ n = leftmost(n->right); } else { while (n->parent && n->parent->right==n){ n = n->parent; } if (!n->parent){ n = nullptr; } else { n = n->parent; } } return *this; } bool operator != (const tree_itor& it) const { return n != it.n; } int& operator * (){ return n->val; } private: node * leftmost(node * n){ while ( n->left ){ n = n->left; } return n; } }; int main ( void ) {try{ auto begin = std::chrono::high_resolution_clock::now(); std::cout << "------------------------" << std::endl; node * tree = build_tree({1, 2, 3, 4, -1, 5, -1, -1, 6, -1, 7, -1, -1, 8, -1, -1, 4, 10, -1, -1, -1 }); print(tree); std::cout << std::endl; tree_itor it(tree); tree_itor itEnd; for ( ; it != itEnd; ++it ){ std::cout << *it << ", "; } std::cout << std::endl; //...... auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration seconds = end - begin; std::cout << "Time: " << seconds.count() << std::endl; return 0; } catch ( const std::exception& e ) { std::cerr << std::endl << "std::exception(\"" << e.what() << "\")." << std::endl; return 2; } catch ( ... ) { std::cerr << std::endl << "unknown exception." << std::endl; return 1; }}