perl 实现二叉树,二叉平衡树

 #! /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;
    }

}

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/xuan_oscar/article/details/4568205
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞