Construct a singly linked list by allocating one node per value and chaining next references. Establishes the node + head + tail model used by every later linked-list lesson.

Algorithm

Canonical input (10, 20, 30, 40) builds the chain head -> 10 -> 20 -> 30 -> 40 -> undef with one node appended per step.

Basic Implementation

basic.pl
use strict; use warnings;
my @values = (10, 20, 30, 40);
my @nodes = ();
my $head = -1;
my $tail = -1;
my $i = 0;
while ($i < scalar @values) {
	my $idx = scalar @nodes;
	push @nodes, { value => $values[$i], next_idx => -1 };
	if ($head == -1) {
		$head = $idx;
	} else {
		$nodes[$tail]->{next_idx} = $idx;
	}
	$tail = $idx;
	$i = $i + 1;
}
my $cur = $head;
while ($cur != -1) {
	print $nodes[$cur]->{value} . " -> ";
	$cur = $nodes[$cur]->{next_idx};
}
print "undef\n";

Complexity

  • Time: O(n) with a tail pointer
  • Space: O(n) for the chain

Implementation notes

  • Perl: a hash reference { value => ..., next_idx => ... } stored in a plain @nodes arena. The integer next_idx field with -1 as the sentinel is the explicit "end-of-list" marker and lets the $head / $tail pointers update the chain without leaning on a recursive blessed-reference graph or Scalar::Util::weaken.
  • The field is named next_idx rather than next because next is a Perl keyword (loop control); using next as a hash key would technically work but reads as a stutter, so the explicit _idx suffix keeps the hash key honest and parallel to the other DSA cohorts.
  • The replay never shows runtime references; nodes are labelled node(<value>) and the chain view is rendered as 10 -> 20 -> ... -> undef.
  • Perl reclaims the arena via reference counting at scope exit, so the build step stays focused on wiring without an explicit free walk.
node chain Each node is a hash reference `{ value => ..., next_idx => ... }` stored in a plain `@nodes` arena. The integer `next_idx` field with `-1` as the sentinel marks the end of the list.