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
|
#include <iostream>
#include <iomanip>
class Node23
{
static Node23* const Unused;
int data[2];
Node23* child[3];
Node23* parent;
public:
// New nodes are always 2-nodes
Node23(int d, Node23* p=nullptr, Node23* a=nullptr, Node23* b=nullptr)
: data{d, 0}, child{a, b}, parent{p} { child[2] = Unused; }
// For manual tree-building we need to make 3-nodes
Node23(int d0, int d1, Node23* p=nullptr,
Node23* a=nullptr, Node23* b=nullptr, Node23* c=nullptr)
: data{d0, d1}, child{a, b, c}, parent{p} { }
~Node23() {
delete child[0]; // delete is okay with nullptr
delete child[1];
if (is3node()) delete child[2]; // but not with our special value
}
// "active" pointer is neither nullptr nor Unused.
static bool active(Node23* node) { return node && node != Unused; }
bool is3node() const { return child[2] != Unused; }
bool is_leaf() const { return child[0] == nullptr; }
bool expand(int d) {
if (is3node())
return false; // will become a 4-node; let caller handle it
if (d < data[0]) {
data[1] = data[0];
data[0] = d;
}
else
data[1] = d;
child[2] = nullptr; // mark as 3-node (overwriting Unused value)
return true;
}
void print(bool top = true) const {
if (child[0]) child[0]->print(false);
std::cout << data[0] << ' ';
if (child[1]) child[1]->print(false);
if (is3node()) {
std::cout << data[1] << ' ';
if (active(child[2])) child[2]->print(false);
}
if (top) std::cout << '\n';
}
void print_structure(int depth = 0) const {
if (is3node()) {
if (active(child[2])) child[2]->print_structure(depth + 1);
std::cout << std::setw(depth * 4) << "" << data[1] << '\n';
}
if (child[1]) child[1]->print_structure(depth + 1);
std::cout << std::setw(depth * 4) << "" << data[0] << '\n';
if (child[0]) child[0]->print_structure(depth + 1);
}
};
Node23* const Node23::Unused = reinterpret_cast<Node23*>(1);
int main() {
// 10
// 3 , 5 15
// 1 4 6 12 18
// Manually create a tree (with null parent pointers for now)
auto a = new Node23(10,
nullptr,
new Node23(3, 5,
nullptr,
new Node23(1),
new Node23(4),
new Node23(6)),
new Node23(15,
nullptr,
new Node23(12),
new Node23(18)));
a->print();
// The structure printout shows the tree sideways.
// Tilt your head to the left to view it. :)
a->print_structure();
delete a;
}
|