use strict;
use warnings;
+use Carp qw/confess/;
use metaclass;
our $VERSION = '0.02';
-BinaryTree->meta->add_attribute('$:uid' => (
+BinaryTree->meta->add_attribute('uid' => (
reader => 'getUID',
writer => 'setUID',
- default => sub {
+ default => sub {
my $instance = shift;
- ("$instance" =~ /\((.*?)\)$/);
+ ("$instance" =~ /\((.*?)\)$/)[0];
}
));
-BinaryTree->meta->add_attribute('$:node' => (
+BinaryTree->meta->add_attribute('node' => (
reader => 'getNodeValue',
writer => 'setNodeValue',
+ clearer => 'clearNodeValue',
init_arg => ':node'
));
-BinaryTree->meta->add_attribute('$:parent' => (
+BinaryTree->meta->add_attribute('parent' => (
predicate => 'hasParent',
reader => 'getParent',
- writer => 'setParent'
+ writer => 'setParent',
+ clearer => 'clearParent',
));
-BinaryTree->meta->add_attribute('$:left' => (
- predicate => 'hasLeft',
+BinaryTree->meta->add_attribute('left' => (
+ predicate => 'hasLeft',
+ clearer => 'clearLeft',
reader => 'getLeft',
- writer => {
+ writer => {
'setLeft' => sub {
my ($self, $tree) = @_;
- $tree->setParent($self) if defined $tree;
- $self->{'$:left'} = $tree;
- $self;
+ confess "undef left" unless defined $tree;
+ $tree->setParent($self) if defined $tree;
+ $self->{'left'} = $tree;
+ $self;
}
},
));
-BinaryTree->meta->add_attribute('$:right' => (
- predicate => 'hasRight',
+BinaryTree->meta->add_attribute('right' => (
+ predicate => 'hasRight',
+ clearer => 'clearRight',
reader => 'getRight',
writer => {
'setRight' => sub {
- my ($self, $tree) = @_;
- $tree->setParent($self) if defined $tree;
- $self->{'$:right'} = $tree;
- $self;
+ my ($self, $tree) = @_;
+ confess "undef right" unless defined $tree;
+ $tree->setParent($self) if defined $tree;
+ $self->{'right'} = $tree;
+ $self;
}
}
));
sub new {
my $class = shift;
- $class->meta->new_object(':node' => shift);
-}
-
+ $class->meta->new_object(':node' => shift);
+}
+
sub removeLeft {
my ($self) = @_;
my $left = $self->getLeft();
- $left->setParent(undef);
- $self->setLeft(undef);
+ $left->clearParent;
+ $self->clearLeft;
return $left;
}
sub removeRight {
my ($self) = @_;
my $right = $self->getRight;
- $right->setParent(undef);
- $self->setRight(undef);
+ $right->clearParent;
+ $self->clearRight;
return $right;
}
-
+
sub isLeaf {
- my ($self) = @_;
- return (!$self->hasLeft && !$self->hasRight);
+ my ($self) = @_;
+ return (!$self->hasLeft && !$self->hasRight);
}
sub isRoot {
- my ($self) = @_;
- return !$self->hasParent;
+ my ($self) = @_;
+ return !$self->hasParent;
}
-
+
sub traverse {
- my ($self, $func) = @_;
+ my ($self, $func) = @_;
$func->($self);
- $self->getLeft->traverse($func) if $self->hasLeft;
+ $self->getLeft->traverse($func) if $self->hasLeft;
$self->getRight->traverse($func) if $self->hasRight;
}
sub mirror {
my ($self) = @_;
# swap left for right
- my $left = $self->getLeft;
- $self->setLeft($self->getRight());
- $self->setRight($left);
+ if( $self->hasLeft && $self->hasRight) {
+ my $left = $self->getLeft;
+ my $right = $self->getRight;
+ $self->setLeft($right);
+ $self->setRight($left);
+ } elsif( $self->hasLeft && !$self->hasRight){
+ my $left = $self->getLeft;
+ $self->clearLeft;
+ $self->setRight($left);
+ } elsif( !$self->hasLeft && $self->hasRight){
+ my $right = $self->getRight;
+ $self->clearRight;
+ $self->setLeft($right);
+ }
+
# and recurse
- $self->getLeft->mirror() if $self->hasLeft();
- $self->getRight->mirror() if $self->hasRight();
+ $self->getLeft->mirror if $self->hasLeft;
+ $self->getRight->mirror if $self->hasRight;
$self;
}
sub size {
my ($self) = @_;
my $size = 1;
- $size += $self->getLeft->size() if $self->hasLeft();
- $size += $self->getRight->size() if $self->hasRight();
+ $size += $self->getLeft->size if $self->hasLeft;
+ $size += $self->getRight->size if $self->hasRight;
return $size;
}
my ($self) = @_;
my ($left_height, $right_height) = (0, 0);
$left_height = $self->getLeft->height() if $self->hasLeft();
- $right_height = $self->getRight->height() if $self->hasRight();
+ $right_height = $self->getRight->height() if $self->hasRight();
return 1 + (($left_height > $right_height) ? $left_height : $right_height);
-}
+}
-1;
\ No newline at end of file
+1;