From ceff1eb36bffd4fa2602beba865b26f04a19b504 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 17 Feb 2018 22:39:24 +1300 Subject: Initial commit --- binary-tree/binary-tree.pl | 79 +++++++++++++++++++++++++++++++++++++++++ linked-list/linked-list-demo.pl | 74 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 binary-tree/binary-tree.pl create mode 100644 linked-list/linked-list-demo.pl diff --git a/binary-tree/binary-tree.pl b/binary-tree/binary-tree.pl new file mode 100644 index 0000000..9a23055 --- /dev/null +++ b/binary-tree/binary-tree.pl @@ -0,0 +1,79 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use utf8; + +use 5.006; + +# Start with an empty tree +my $root = undef; + +# Read lines one by one +while ( defined( my $line = <> ) ) { + + # Create a new node with this line's value, and empty "left" and "right" + # references + my $new = { + line => $line, + left => undef, + right => undef, + }; + + # If the tree is empty, this can be our first node; skip the rest of this + # iteration + if ( not defined $root ) { + $root = $new; + next; + } + + # Starting at the root ... + my $cur = $root; + + # Until we don't have any more nodes for comparison (i.e. we've found the + # place for our new node)... + while ( defined $cur ) { + + # Decide whether to add this to the "left" subtree or the "right" + # subtree, depending on whether it's less than the current node or not + my $dir = + $line lt $cur->{line} + ? 'left' + : 'right'; + + # If that reference is undefined, then that's where we'll put this new + # node; unset $cur so the loop stops + if ( not defined $cur->{$dir} ) { + $cur->{$dir} = $new; + $cur = undef; + next; + } + + # Otherwise, we resume descent with the next node + $cur = $cur->{$dir}; + } +} + +# Start a stack of node items to fall back to once we've processed a node, and +# begin at the root +my @stack; +my $cur = $root; + +# Keep going as long as there are nodes left in the stack or we have a +# "current" node to print +while ( @stack or defined $cur ) { + + # Drill down through the "left" nodes, stacking them up, until we hit NULL + while ( defined $cur ) { + push @stack, $cur; + $cur = $cur->{left}; + } + + # If there is anything in the stack after doing that, pop off the first + # one, print it, and then move to its "right" node + if (@stack) { + $cur = pop @stack; + print "\t$cur->{line}"; + $cur = $cur->{right}; + } +} diff --git a/linked-list/linked-list-demo.pl b/linked-list/linked-list-demo.pl new file mode 100644 index 0000000..069cb3c --- /dev/null +++ b/linked-list/linked-list-demo.pl @@ -0,0 +1,74 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use utf8; + +use 5.006; + +# Two pointers: one to the head of the list, one to the "current" node +my $head = undef; +my $cur = undef; + +### Build the list: + +# Read lines of text, and add a new node to the list each time +while ( defined( my $line = <> ) ) { + + # Make a new node: a hashref with two fields; one with our read line, and + # one pointing to the "next" node, and there isn't one yet, so we'll make + # that undef + my $new = { + line => $line, + next => undef, + }; + + # If $head doesn't yet point anywhere, this is the first node in our list, + # so Make that our starting point + if ( not defined $head ) { + $head = $new; + } + + # Otherwise, we make the new node the "next" one of the last one we created + else { + $cur->{next} = $new; + } + + # The node we just created then becomes our "current" node. + $cur = $new; +} + +### Print the list: + +# Starting at $head, print the node's text and follow its "next" until it's +# "undef", i.e. we've reached the end of the chain. +print "Pre-insert:\n"; +for ( $cur = $head ; defined $cur ; $cur = $cur->{next} ) { + print "\t$cur->{line}"; +} + +### Insert into the list: + +# Add a node with string "lmao" after any node with string "ayy" +for ( $cur = $head ; defined $cur ; $cur = $cur->{next} ) { + + # Just keep walking if we don't match + next if $cur->{line} ne "ayy\n"; + + # Make a new node, and make its next node whatever the current node's + # "next" was going to be; we're stealing its link, inserting it into the + # chain. + my $new = { + line => "lmao\n", + next => $cur->{next}, + }; + + # Re-point the current node's "next" to the node we just created. + $cur->{next} = $new; +} + +### Print the list again: +print "Post-insert:\n"; +for ( $cur = $head ; defined $cur ; $cur = $cur->{next} ) { + print "\t$cur->{line}"; +} -- cgit v1.2.3