tree_iterator.cpp

This commit is contained in:
2021-11-21 14:10:00 +00:00
parent a1835ad116
commit fa13178e66

View 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;
}}