summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binary-tree/binary-tree.pl79
-rw-r--r--linked-list/linked-list-demo.pl74
2 files changed, 153 insertions, 0 deletions
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}";
+}