1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
// tree.h
#ifndef TREE_H
#define TREE_H
#include <iostream>
#include <iomanip>
#include <queue>
template <typename T>
class Tree
{
private:
struct Node
{
T data;
Node* left;
Node* right;
Node( const T& data, Node* left = nullptr, Node* right = nullptr )
:data(data), left(left), right(right)
{
}
};
Node *root;
struct BreadthNode
{
const Node* node;
int depth;
BreadthNode( const Node* node, const int depth ): node(node), depth( depth ){}
bool operator>( const BreadthNode& other ) const
{
return depth > other.depth;
}
};
typedef std::priority_queue< BreadthNode, std::vector< BreadthNode>, std::greater<BreadthNode> > breadth_queue;
public:
Tree( void ) : root( nullptr ) {}
virtual ~Tree( void )
{
destroy( root );
}
private:
void destroy( Node* current )
{
if ( !current ) return;
destroy( current->left );
destroy( current->right );
delete current;
}
public:
void insert( const T& value )
{
root = insert( root, value );
}
protected:
virtual Node* insert( Node* current, const T& value )
{
if ( !current ) return new Node( value );
if ( current->data > value ) current->left = insert( current->left, value );
if ( current->data < value ) current->right = insert( current->right, value );
return current;
}
public:
void print( void ) const
{
std::cout << "left to right print:\n";
print( root, 0 );
std::cout << '\n';
std::cout << "breath first print:\n";
breadth_queue queue;
create_queue( root, 0, queue );
print_queue( queue );
}
private:
void print( const Node* current, const int depth ) const
{
if ( !current ) return;
print( current->left, depth + 1 );
std::cout << std::setw( 10 ) << current << " "
<< std::setw( 10 ) << current->left << " "
<< std::setw( 10 ) << current->right << " "
<< std::setw( 3 ) << current->data << " "
<< std::setw( 3 ) << depth << '\n';
print( current->right, depth + 1 );
}
void create_queue( const Node* current, const int depth, breadth_queue& queue ) const
{
if ( !current ) return;
queue.push( BreadthNode( current, depth ) );
create_queue( current->left, depth + 1, queue );
create_queue( current->right, depth + 1, queue );
}
void print_queue( breadth_queue& queue ) const
{
while ( !queue.empty() )
{
const Node* current = queue.top().node;
std::cout << std::setw( 10 ) << current << " "
<< std::setw( 10 ) << current->left << " "
<< std::setw( 10 ) << current->right << " "
<< std::setw( 3 ) << current->data << " "
<< std::setw( 3 ) << queue.top().depth << '\n';
queue.pop();
}
}
};
#endif
|