tree_iterator.cpp
This commit is contained in:
146
puzzles/training/tree_iterator.cpp
Normal file
146
puzzles/training/tree_iterator.cpp
Normal file
@@ -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 <iostream>
|
||||
#include <exception>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
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<int>& 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<double> 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;
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user