Pascal Data Structures Tutorial: Arrays, Pointers, Stacks & Trees
Pascal doesn't run the world's production servers anymore, but it's still one of the clearest languages for actually understanding how data structures work under the hood. Its explicit typing and readable syntax strip away the noise that C and its descendants add, so when you write a linked list or a binary tree in Pascal, you're looking straight at the mechanics instead of fighting the language.
This Pascal data structures tutorial walks through the core building blocks every introductory computer science course covers: arrays, pointers, linked lists, stacks, queues, binary trees, recursion, and sorting. Each section includes a short, runnable example you can type into any Pascal compiler, including free ones like Free Pascal.
![]() |
| Cr Image: ChatGPT. |
Arrays: the starting point
An array is the simplest data structure Pascal offers: a fixed block of memory holding values of the same type, accessed by index.
program ArrayDemo;
var
scores: array[1..5] of Integer;
i, total: Integer;
begin
total := 0;
for i := 1 to 5 do
begin
Write('Enter score ', i, ': ');
ReadLn(scores[i]);
total := total + scores[i];
end;
WriteLn('Average score: ', total / 5:0:2);
end.
Arrays are fast and predictable because Pascal reserves the memory upfront and every element sits at a fixed offset. The tradeoff is rigidity: once declared, the size doesn't change, which is exactly the limitation pointers and dynamic structures exist to solve.
Pointers and records: building your own structures
A pointer in Pascal holds the address of a variable instead of a value itself. Combined with a record (Pascal's version of a struct), pointers let you build structures that grow and shrink while the program runs, something a fixed array can never do.
type
PNode = ^TNode;
TNode = record
data: Integer;
next: PNode;
end;
This pair, a record type and a pointer to that record, is the foundation almost every dynamic structure in this tutorial builds on. Once you're comfortable allocating a node with New() and releasing it with Dispose(), linked lists, stacks, queues, and trees all become variations on the same idea.
Linked lists
A linked list chains nodes together instead of storing them in contiguous memory. Each node points to the next, so inserting or removing an element only requires updating a couple of pointers rather than shifting an entire array.
program LinkedListDemo;
type
PNode = ^TNode;
TNode = record
data: Integer;
next: PNode;
end;
var
head, current, newNode: PNode;
i, n, value: Integer;
begin
head := nil;
Write('How many numbers? ');
ReadLn(n);
for i := 1 to n do
begin
Write('Enter number ', i, ': ');
ReadLn(value);
New(newNode);
newNode^.data := value;
newNode^.next := nil;
if head = nil then
head := newNode
else
begin
current := head;
while current^.next <> nil do
current := current^.next;
current^.next := newNode;
end;
end;
current := head;
Write('List: ');
while current <> nil do
begin
Write(current^.data, ' ');
current := current^.next;
end;
WriteLn;
end.
Traversal in a linked list is always one direction unless you build a doubly linked version with a prev pointer alongside next. That extra pointer costs a bit of memory per node but makes it possible to walk backward, which matters for structures like undo history or a browser's back button.
Stacks: last in, first out
A stack only allows you to add or remove from one end, the top. Think of a stack of plates: you add to the top and take from the top. This LIFO behavior makes stacks the natural fit for anything involving nested structure, like matching parentheses, tracking function calls, or implementing undo.
program StackDemo;
type
PNode = ^TNode;
TNode = record
data: Integer;
next: PNode;
end;
var
top: PNode;
procedure Push(value: Integer);
var newNode: PNode;
begin
New(newNode);
newNode^.data := value;
newNode^.next := top;
top := newNode;
end;
function Pop: Integer;
var temp: PNode;
begin
Pop := top^.data;
temp := top;
top := top^.next;
Dispose(temp);
end;
begin
top := nil;
Push(10);
Push(20);
Push(30);
WriteLn('Popped: ', Pop);
WriteLn('Popped: ', Pop);
WriteLn('Popped: ', Pop);
end.
Notice that Push and Pop only ever touch the top pointer. That's the entire point of a stack: every operation is O(1) because you never need to search or shift anything.
Queues: first in, first out
A queue behaves like a line at a checkout counter. Whoever joins first gets served first. Where a stack removes from the same end it adds to, a queue adds at the back and removes from the front, which means you generally need to track two pointers instead of one.
type
PNode = ^TNode;
TNode = record
data: Integer;
next: PNode;
end;
var
front, rear: PNode;
procedure Enqueue(value: Integer);
var newNode: PNode;
begin
New(newNode);
newNode^.data := value;
newNode^.next := nil;
if rear = nil then
begin
front := newNode;
rear := newNode;
end
else
begin
rear^.next := newNode;
rear := newNode;
end;
end;
Queues show up constantly in real systems: print job scheduling, request handling, breadth-first search in graphs. Anywhere fairness matters, meaning the thing that arrived first should be handled first, a queue is usually the right structure.
Binary trees
A binary tree extends the linked-node idea into two dimensions. Instead of one next pointer, each node has a left and a right pointer, which lets you represent hierarchy rather than a flat sequence.
type
PTreeNode = ^TTreeNode;
TTreeNode = record
data: Integer;
left, right: PTreeNode;
end;
procedure Insert(var root: PTreeNode; value: Integer);
begin
if root = nil then
begin
New(root);
root^.data := value;
root^.left := nil;
root^.right := nil;
end
else if value < root^.data then
Insert(root^.left, value)
else
Insert(root^.right, value);
end;
This particular arrangement, smaller values to the left and larger to the right, is a binary search tree. It keeps lookups fast because at every node you can discard half the remaining tree, similar in spirit to how binary search works on a sorted array.
Recursion: fibonacci and factorial
Pascal handles recursion cleanly, which makes it a good language for seeing the concept without extra syntax getting in the way. A recursive function calls itself with a smaller version of the same problem until it hits a base case.
function Factorial(n: Integer): LongInt; begin if n <= 1 then Factorial := 1 else Factorial := n * Factorial(n - 1); end; function Fibonacci(n: Integer): Integer; begin if n <= 1 then Fibonacci := n else Fibonacci := Fibonacci(n - 1) + Fibonacci(n - 2); end;
The Fibonacci version above is intentionally simple rather than efficient. It recalculates the same values repeatedly, so for anything beyond small inputs, an iterative version or one that caches previous results runs dramatically faster. It's still worth writing the naive version first, because seeing exactly where the redundant calls happen is what makes the optimization obvious later.
Sorting: bubble sort
Bubble sort isn't fast, but it's the clearest starting point for understanding how sorting algorithms work: repeatedly compare neighboring elements and swap them if they're out of order.
procedure BubbleSort(var arr: array of Integer; n: Integer);
var
i, j, temp: Integer;
begin
for i := 0 to n - 2 do
for j := 0 to n - 2 - i do
if arr[j] > arr[j + 1] then
begin
temp := arr[j];
arr[j] := arr[j + 1];
arr[j + 1] := temp;
end;
end;
Each full pass pushes the largest remaining value to its correct position, the same way a bubble rises to the top. Once you understand why this approach is O(n²), algorithms like merge sort and quicksort make a lot more sense, since they exist specifically to avoid that quadratic cost.
Where to go from here
Arrays, pointers, linked lists, stacks, queues, trees, recursion, and sorting cover most of what a first data structures course expects. The natural next step is combining them: a queue built from a linked list, a tree traversal that uses a stack instead of recursion, or a hash table that resolves collisions with linked lists at each bucket. Once the individual pieces feel familiar, mixing and matching them is where the subject actually gets interesting.

Post a Comment for "Pascal Data Structures Tutorial: Arrays, Pointers, Stacks & Trees"