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