#! /usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
my $head = undef;
my $copy = /$head;
foreach my $index( 1 .. 10 ){
&AVLTree_insert($copy, $index);
}
#&create_BSTree( $copy );
#&create_tree( $copy );
print Dumper ( $head );
&tree_delete( $copy, 1 );
print Dumper ( $head );
#&afterward_travel($head);
#&middle_travel($head);
#&layer_travel ( $head );
#&search_BST( $head, 23);
sub max{
my ( $a, $b) = @_;
return $a > $b ? $a : $b;
}
sub ll_rotate {
my $root = shift;
my $x = $$root;
my $y = $x->{left};
$x->{left} = $y->{right};
$y->{right} = $x;
$$root = $x;
$x->{height} = &max( &height( $x->{left} ), &height( $x->{right} ) ) + 1;
$y->{height} = &max( &height( $y->{left} ), &height( $y->{right} )) + 1;
}
sub rr_rotate {
my $root = shift;
my $x = $$root;
my $y = $x->{right};
$x->{right} = $y->{left};
$y->{left} = $x;
$$root = $y;
$x->{height} = &max( &height( $x->{left} ), &height( $x->{right} ) ) + 1;
$y->{height} = &max( &height( $y->{left} ), &height( $y->{right} ) ) + 1;
}
sub lr_rotate {
my $root = shift;
my $x = $$root;
my $y = $x->{left};
&rr_rotate( /$x->{left});
&ll_rotate ( $root);
}
sub rl_rotate {
my $root = shift;
my $x = $$root;
my $y = $x->{right};
&ll_rotate( /$x->{right});
&rr_rotate( $root);
}
sub AVLTree_insert{
my ( $tree, $value ) = @_;
if ( !defined $$tree ){
$$tree = {
height => 0,
left => undef,
right => undef,
value => $value,
}
}
else {
if ( $$tree->{value} > $value ){
&AVLTree_insert( /$$tree->{left}, $value);
if ( (&height( $$tree->{left} ) – &height( $$tree->{right}) ) == 2 ){
if ($value < $$tree->{left}->{value}){
&ll_rotate( $tree );
}
else {
&lr_rotate( $tree );
}
}
}
else{
&AVLTree_insert( /$$tree->{right}, $value);
if ( ( &height( $$tree->{right} ) – &height( $$tree->{left} )) == 2){
if ( $value > $$tree->{right}->{value}){
&rr_rotate ( $tree );
}
else {
&rl_rotate( $tree );
}
}
}
$$tree->{height} = &max( &height($$tree->{left}), &height( $$tree->{right} )) + 1;
}
}
sub AVLTree_delete{
my ( $tree, $value ) = @_;
}
sub BBST_delete_node{
my ( $tree, $value ) = @_;
if ( $$tree->{value} == $value ){
if ( !defined $$tree->{left} && !defined $$tree->{right} ){
$$tree = undef;
}
elsif ( !defined $$tree->{left} && defined $$tree->{right} ){
$$tree = $$tree->{right};
}
elsif ( defined $$tree->{left} && !defined $$tree->{right} ) {
$$tree = $$tree->{left};
}
else {
my $temp = $$tree->{right};
while ( defined $temp->{left} ){
$temp = $temp->{left};
}
my $key = $temp->{left};
$temp->{left} = $temp->{left}->{right};
$key->{left} = $$tree->{left};
$key->{right} = $$tree->{right};
$$tree = $key;
}
}
}
sub assign{
my ( $parent, $child, $value ) = @_;
if ($parent->{left} eq $child ){
$parent->{left} = $value;
}
else {
$parent->{right} = $value;
}
}
sub tree_delete{
my ( $tree, $value ) = @_;
my @stack ;
my $temp = $$tree;
while ( defined $temp ){
push @stack, $temp;
if ( $temp->{value} == $value ){
if ( !defined $temp->{left} && !defined $temp->{right} ){
pop @stack;
my $parent = $stack[-1];
&assign( $parent, $temp, undef);
}
elsif ( !defined $temp->{left} && defined $temp->{right} ){
pop @stack;
my $parent = $stack[-1];
&assign( $parent, $temp, $temp->{right});
}
elsif ( defined $temp->{left} && !defined $temp->{right} ) {
pop @stack;
my $parent = $stack[-1];
&assign( $parent, $temp, $temp->{left});
}
else {
my $min = $temp->{right};
while ( defined $min->{left} ){
push @stack, $min;
$min = $min->{left};
}
$temp->{value} = $min->{value};
my $parent = $stack[-1];
&assign( $parent, $min, $min->{right});
}
$$tree = $temp if ($$tree eq $temp );
$temp = undef;
}
elsif ( $temp->{value} > $value ){
$temp = $temp->{left};
}
else {
$temp = $temp->{right};
}
}
my $parent;
while ( scalar @stack ){
$parent = pop @stack;
if ( &height( $parent->{left} ) – &height( $parent->{right} ) == 2 ){
if ( &height( $parent->{left}->{left}) > &height( $parent->{left}->{right} )){
ll_rotate(/$parent);
}
else{
lr_rotate(/$parent);
}
}
elsif ( &height( $parent->{left} ) – &height( $parent->{right} )== -2 ){
if ( &height( $parent->{right}->{left}) > &height( $parent->{right}->{right})){
rl_rotate( /$parent );
}
else {
rr_rotate( /$parent );
}
}
$parent->{height} = &max( &height($parent->{left}), &height( $parent->{right})) + 1;
}
$$tree = $parent;
}
sub height{
my $root = shift;
return defined $root ? $root->{height} : -1;
}
sub create_tree{
my $child = shift;
my $value = <STDIN>;
chomp $value;
if ( $value eq “” ){
$child = undef;
}
else{
my $node = {
left => undef,
right => undef,
value => $value,
};
$$child = $node;
&create_tree( /$node->{left} );
&create_tree( /$node->{right} );
}
}
sub middle_travel {
my $tree = shift;
my @stack;
if ( defined $tree ){
my $temp = $tree;
while ( ( scalar @stack ) || defined $temp ){
while ( defined ( $temp ) ){
push (@stack, $temp);
$temp = $temp->{left};
}
$temp = pop @stack;
print $temp->{value};
$temp = $temp->{right};
}
}
}
sub afterward_travel {
my $tree = shift;
my @stack;
my @flags;
if ( defined $tree ) {
my $temp = $tree;
do {
while ( defined( $temp ) ){
push @stack, $temp;
push @flags, 0 ;
$temp = $temp->{left};
}
$temp = pop ( @stack );
my $flag = pop ( @flags );
if ( $flag == 0 ){
push @flags, 1;
push @stack, $temp;
$temp = $temp->{right};
}
else {
print $temp->{value} ;
$temp = undef;
}
} while ( ( scalar @stack ) || defined $temp );
}
}
sub layer_travel {
my $tree = shift;
if ( defined $tree ){
my $temp = $tree;
my ( @queue, $node );
push @queue, $temp;
while ( scalar @queue ){
$node = shift @queue;
print $node->{value};
if ( defined $node->{left} ){
push @queue, $node->{left};
}
if ( defined $node->{right} ){
push @queue, $node->{right}
}
}
}
}
sub create_BSTree{
my $child = shift;
while ( <STDIN> ){
chomp ;
if ( $_ eq “” ){
last;
}
else {
my $value = $_;
if ( ! defined $$child ){
$$child->{value} = $value;
$$child->{left} = undef;
$$child->{right} = undef;
}
else{
my $flag ;
my $parent;
my $temp = $$child;
while ( $temp ){
$parent = $temp;
if ( $temp->{value} > $value ){
$temp = $temp->{left};
$flag = 0;
}
elsif ( $temp->{value} < $value ){
$temp = $temp->{right};
$flag = 1;
}
}
my $node = {
value => $value,
left => undef,
right => undef,
};
$flag ? $parent->{right} = $node : $parent->{left} = $node;
}
}
}
}
sub search_BST {
my ($tree, $value) = @_;
if ( $tree ){
if ( $tree->{value} > $value ){
&search_BST( $tree->{left}, $value);
}
elsif ( $tree->{value} < $value ){
&search_BST( $tree->{right}, $value)
}
else{
print “I find it”;
return;
}
}
else {
print “I can not find it “;
return /$tree;
}
}