diff --git a/puzzles/training/tree_iterator.cpp b/puzzles/training/tree_iterator.cpp new file mode 100644 index 0000000..f56b484 --- /dev/null +++ b/puzzles/training/tree_iterator.cpp @@ -0,0 +1,146 @@ +/* +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; +}} +