ITC 120 › Prelim › Linked lists
Linear data structures · Lesson 2 of 4
Linked lists
This lesson teaches:Data structureAlgorithmA chain of nodes. Nothing shifts: we change the arrows instead.
By the end, you can:
- explain how nodes and references form a linked list;
- trace access, traversal, insertion, and deletion on a box-and-arrow drawing and in Java, and write a method that adds a node at the end;
- compare a linked list with an array: which tasks each one does faster, and when to use each;
- explain why the order of the lines matters when inserting;
- tell singly, doubly, and circular linked lists apart.
You need: the Arrays lesson, and scratch paper for drawing boxes and arrows.
Part 1 · The idea
A chain of nodes
The array's one real weakness: to insert 25 at index 2 of 10, 20, 30, 40, both 30 and 40 had to move. The more values after the gap, the more work. So what if the values did not have to sit side by side at all?
Linked list
A linked list is a linear data structure (a way to organize data where the items form one line, each item followed by at most one next item) made of a chain of nodes. A node is one small box of data in the chain. Each node stores two things: the value (data), and where to find the next node (next). A variable called head refers to the first node. The last node's next is null: the end. An empty list has head equal to null.
Like a treasure hunt
Each clue tells you where the next clue is hidden. To reach clue 4, you start at clue 1 and follow the clues in order. You cannot jump to clue 4. The first clue is like head, each hiding place is like next, and "this is the last clue" is like null.
Here is the same sequence, organized two ways:
Side by side:
| Array | Linked list |
|---|---|
| Numbered slots, side by side. | Nodes can be anywhere in memory. |
| The index tells you where to go. | The previous node tells you where to go next. |
| Reach any slot in one step. | Walk from head, one link at a time. |
| Insert or delete: shift values. | Insert or delete: change links. |
Part 2 · Java first
Nodes and references in Java
Before the code, two words you will use in every lesson from now on: class and object. Think of a polvoron mold. You cannot eat the mold; it only decides the shape. Each time you press it, you get one real polvoron, and each one can have its own flavor.
Class and object
A class is a blueprint: it describes what every object of that kind will have (its fields, the variables inside each object) and what it can do (its methods). An object is one real thing made from the class with new. One class can make many objects, and each object keeps its own values.
In this lesson, the class is Node, and every node in a list is one object made from it. Here is the class:
1class Node {
2 int data; // the value stored in this node
3 Node next; // reference to the next node (null if none)
4
5 Node(int value) { // constructor: runs once for each new Node(...)
6 data = value;
7 next = null; // a new node has no next node yet
8 }
9} Reference
A reference tells Java where to find an object. It is not the object itself. The special value null refers to no object.
| Line | Meaning |
|---|---|
int data; | A field: a variable inside each node object. It holds that node's value, and every node has its own. |
Node next; | A field that holds a reference to another node, or null. |
Node(int value) | The constructor: same name as the class, no return type. It runs once, automatically, each time new Node(...) runs. |
Each new makes one more object from the same blueprint:
data and its own next.Node first = new Node(10); does three things: new creates a node in memory, the constructor stores 10 in data and null in next, and = stores a reference to that node in the variable first. (The name first is our choice, not a Java keyword.)
Assignment copies the reference, not the node
Node a = new Node(5);
Node b = a; // b refers to the SAME node as a
b.data = 9; // changes that one node
System.out.println(a.data); // prints 9 Node b = a; does not make a new node. It gives the same node a second name. Like a classmate with two names, Migs and Miguel: if Migs gets a new shirt number, Miguel has it too, because they are the same person. Compare Node b = new Node(5);, which makes a separate node: changing b.data would not touch a.data.
The dot in b.data means "the data field of the node that b refers to." (In the Stacks lesson, objects also have methods, and the dot runs them: s.push(4).)
Connecting two nodes
Node ten = new Node(10);
Node twenty = new Node(20);
ten.next = twenty; // connects node 10 to node 20 ten.next now stores a reference to node 20, not the number 20. The number is ten.next.data.
NullPointerException
An exception is an error Java reports while the program is running; if nothing handles it, the program stops. If a reference is null, using .data or .next on it throws (reports) a NullPointerException, and the program stops at that line. Before writing x.next, ask: can x be null here?
Part 3 · Operations 1 and 2
Accessing and traversing a linked list
Access and traversal
Access means getting one item. Traversal means visiting every item, one by one, in order. You met both in the Arrays lesson. In a linked list, both start at head and follow the next links.
This code builds the list 10 → 20 → 30 and prints it. We keep the name twenty for node 20, so later steps can use it without searching.
Node head = new Node(10); // head refers to node 10
Node twenty = new Node(20);
head.next = twenty; // 10 -> 20
twenty.next = new Node(30); // 20 -> 30
printList(head); // 10 -> 20 -> 30 -> null Here is printList:
1static void printList(Node start) {
2 Node current = start; // start at the first node
3 while (current != null) { // while there is a node here
4 System.out.print(current.data + " -> ");
5 current = current.next; // move to the next node
6 }
7 System.out.println("null"); // mark the end
8} When main calls printList(head), start gets a copy of head's reference. Then current copies it again. All three refer to node 10, but they are separate variables. current = current.next; moves only current. It does not move any node, and it does not change head.
Two words in the first line: static lets main call printList directly, without making an object first, and void means it sends no value back (it only prints). Also, each method has its own variables: the current inside printList is separate from the current that main declares later in the whole program, even though the names match.
Step through it on the list 10 → 20 → 30. Watch current (orange) move while head and start stay on node 10.
Walkthrough: printList(head) on 10 → 20 → 30
Use Next to go step by step, or tap a line to jump to it.
current → 10
start got a copy of head's reference. current copies it again: all three refer to node 10.
1static void printList(Node start) { 2 Node current = start; 3 while (current != null) { 4 System.out.print(current.data + " -> "); 5 current = current.next; 6 } 7 System.out.println("null"); 8} Show the same walk in one table
| current | This step prints | Then |
|---|---|---|
| 10 | 10 -> | move to 20 |
| 20 | 20 -> | move to 30 |
| 30 | 30 -> | 30's next is null, so current becomes null |
| null | (the loop stops) | print null |
Output: 10 -> 20 -> 30 -> null
Forgetting current = current.next;
Without that line, current never moves. It stays on node 10, so current != null is true forever: the loop prints 10 -> again and again and never ends.
Walkthrough: the loop without the move line
Use Next to go step by step, or tap a line to jump to it.
current → 10
current starts at node 10, like before.
1Node current = head; 2while (current != null) { 3 System.out.print(current.data + " -> "); 4 // forgot: current = current.next; 5} null, two ways
In current != null, null is a reference value: "no node." In System.out.println("null"), it is just text in quotation marks that the program prints.
Access is the same walk, stopped early: to get the third node, start at head and follow two links. An array reaches arr[2] in one step. A linked list walks.
Part 4 · Operation 3
Insertion: change links, not values
Insert at the beginning
Start with 10 → 20 → 30. Insert 5 before 10:
Walkthrough: insert 5 at the beginning
Use Next to go step by step, or tap a line to jump to it.
newNode → 5
new makes node 5. Its next is null, so it is not connected to the list yet. head still refers to 10.
1Node newNode = new Node(5); 2newNode.next = head; // step 1 3head = newNode; // step 2 Nothing shifted. Two references changed.
Swap the lines, and the list is lost
If head = newNode; runs first, then newNode.next = head; copies the new head, so node 5 refers to itself. Nothing refers to node 10 anymore, and printList(head) prints 5 forever.
Walkthrough: the same lines, swapped
Use Next to go step by step, or tap a line to jump to it.
newNode → 5
Same start as before: node 5 exists, but it is not connected yet.
1Node newNode = new Node(5); 2head = newNode; // WRONG: done first 3newNode.next = head; Insert after a node you already have
Start with 10 → 20 → 30, and current refers to node 20. Insert 25 after it:
Walkthrough: insert 25 after node 20
Use Next to go step by step, or tap a line to jump to it.
current → 20
Start with 10 → 20 → 30. We already have current on node 20, so no search is needed.
1// current refers to node 20 2Node newNode = new Node(25); 3newNode.next = current.next; // step 1 4current.next = newNode; // step 2 current.next is the reference stored in node 20, which refers to node 30. So line 3 makes 25 refer to 30. Then line 4 makes 20 refer to 25. Result: 10 → 20 → 25 → 30.
Here we already had a reference to node 20. To insert after a value, you would first traverse to find that node.
The safe order for inserting
- First, make the new node refer to the node that will follow it.
- Then, change the old reference to point to the new node.
If B is the only thing pointing to C, and you change B first, nothing points to C anymore. The rest of the list is unreachable. You can watch it happen with "Insert: wrong order!" in the lab (Part 6).
Part 5 · Operation 4
Deletion: link around the node
Delete the node after another one
Start with 10 → 20 → 25 → 30. To delete 25, we need a reference to the node before it, because a singly linked list cannot go backward. previous refers to node 20:
Walkthrough: delete the node after 20
Use Next to go step by step, or tap a line to jump to it.
previous → 20
Start with 10 → 20 → 25 → 30. To delete 25, we need the node before it: previous is on 20.
1// previous refers to node 20 2previous.next = previous.next.next; Read it piece by piece: previous.next is node 25. previous.next.next is node 25's next, which is node 30. Storing that in previous.next makes 20 point to 30. Node 25 is no longer reachable from head, so it is no longer in the list. Nothing else moves.
Is node 25 gone? It is out of the list. Once nothing at all refers to a node, Java's garbage collector (the part of Java that cleans up unused objects) frees its memory later. You do not delete it yourself. (In the whole program below, the variable newNode still refers to node 25, so that node still exists for now.)
This line needs previous != null and previous.next != null. Otherwise it uses a null reference and throws a NullPointerException.
Delete the first node
Deleting the first node only moves head:
head = head.next; // head refers to the second node 5 → 10 → 20 → 30 becomes 10 → 20 → 30. This needs head != null (a list that is not empty). If the list had only one node, head becomes null: the list is now empty.
The whole program
Here is everything together. The program runs all four operations one after another on one list, so its lists are a little longer than the short examples above. Run it and match each output line to its printList call.
Show the complete program
1class Node {
2 int data;
3 Node next;
4 Node(int value) {
5 data = value;
6 next = null;
7 }
8}
9
10public class Main {
11 static void printList(Node start) {
12 Node current = start;
13 while (current != null) {
14 System.out.print(current.data + " -> ");
15 current = current.next;
16 }
17 System.out.println("null");
18 }
19
20 public static void main(String[] args) {
21 Node head = new Node(10);
22 Node twenty = new Node(20);
23 head.next = twenty;
24 twenty.next = new Node(30);
25 printList(head);
26
27 // 1. insert 5 at the beginning
28 Node newNode = new Node(5);
29 newNode.next = head;
30 head = newNode;
31 printList(head);
32
33 // 2. insert 25 after node 20
34 Node current = twenty;
35 newNode = new Node(25);
36 newNode.next = current.next;
37 current.next = newNode;
38 printList(head);
39
40 // 3. delete the node after 20 (bypass it)
41 Node previous = twenty;
42 previous.next = previous.next.next;
43 printList(head);
44
45 // 4. delete the first node
46 head = head.next;
47 printList(head);
48 }
49} ▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.
10 -> 20 -> 30 -> null
5 -> 10 -> 20 -> 30 -> null
5 -> 10 -> 20 -> 25 -> 30 -> null
5 -> 10 -> 20 -> 30 -> null
10 -> 20 -> 30 -> null The real cost
Changing links is cheap. Finding the node is not:
Here is what each task costs:
| Task | Array | Linked list |
|---|---|---|
| Get the value at index 500 (the 501st item) | 1 step | start at head and follow 500 links |
| Insert at a spot you already reached | shift every later value | change 2 links |
| Delete the last value | just reduce the size | walk to the node before it |
Not always faster
Linked lists edit faster, once you are there. Arrays reach faster. Pick the one that fits what the program does most.
Part 6 · Watch it
The linked list lab
Now watch every operation from Parts 3 to 5 again, one line of Java at a time. Each button starts from a short list, so you can replay any of them. Try "Insert: wrong order!" to see the mistake from Part 4 happen.
Linked list lab
Pick an operation and tap Next step. Each step runs one line of Java. Watch which arrow changes.
Swipe the picture sideways to see the whole list.
Color key
Part 7 · Three kinds
Singly, doubly, and circular
Singly linked
Each node knows only what comes next. It moves forward only. To reach the node before B, start over from the head. Like checking attendance from the top of the class list to the bottom.
Doubly linked
Each node also has a prev link, so it moves both ways. The cost: more memory, and more links to update on every change. Like a photo viewer with Next and Previous buttons.
Circular
The last node points back to the first. There is no null at the end, so a loop must stop when it gets back to where it started. Like a cleaning duty schedule that returns to the first name.
Here they are side by side:
| Singly | Doubly | Circular | |
|---|---|---|---|
| Links per node | next | prev and next | next, or both |
| Move backward? | no | yes | only if doubly |
| End of the list | last next is null | null at both ends | loops back to the first |
| Remove a node you have | need the node before it | directly, using prev | depends on singly or doubly |
| Trade-off | one direction only | more memory and updates | needs a stop rule |
Circular is not a third number of links
"Circular" describes the loop, not how many links each node has. A circular list can be singly or doubly linked. A playlist on repeat with Next and Previous is circular doubly linked.
Doubly and circular lists in Java (extra)
Extra topic. Writing doubly and circular lists in Java goes beyond this course. You only need to tell the three kinds apart and give a trade-off for each, as in the table above. Open this if you are curious.
Show doubly and circular lists in Java
The four operations are the same as in a singly list. Two things change: how many links you update, and how a loop knows when to stop.
Doubly linked: insert after a node. Each node has one new field, prev, the node before it. In a singly list, inserting after a node changed 2 links (the safe order ). In a doubly list it changes 4: two for the new node, and one for each neighbor.
Here are the four changes, in order:
| Step | Code | In words |
|---|---|---|
| 1 | newNode.prev = current; | 25 looks back at 20 |
| 2 | newNode.next = current.next; | 25 looks ahead at 30 |
| 3 | current.next.prev = newNode; | 30 looks back at 25 |
| 4 | current.next = newNode; | 20 looks ahead at 25 |
The safe order is the same idea as before: give the new node its links first (steps 1 and 2), then point the neighbors at it (steps 3 and 4). If you do step 4 first, current.next is already 25, so step 2 makes 25 point at itself, and 30 is lost.
1public class DoublyDemo {
2 // insert newNode right after current: 4 links change
3 static void insertAfter(DNode current, DNode newNode) {
4 newNode.prev = current; // step 1: 25 looks back at 20
5 newNode.next = current.next; // step 2: 25 looks ahead at 30
6 if (current.next != null) { // (no next node at the end)
7 current.next.prev = newNode; // step 3: 30 looks back at 25
8 }
9 current.next = newNode; // step 4: 20 looks ahead at 25
10 }
11
12 public static void main(String[] args) {
13 DNode head = new DNode(20);
14 DNode tail = new DNode(30);
15 head.next = tail;
16 tail.prev = head;
17
18 insertAfter(head, new DNode(25));
19
20 DNode current = head; // forward, using next
21 while (current != null) {
22 System.out.print(current.data + " ");
23 current = current.next;
24 }
25 System.out.println(); // 20 25 30
26
27 current = tail; // backward, using prev
28 while (current != null) {
29 System.out.print(current.data + " ");
30 current = current.prev;
31 }
32 System.out.println(); // 30 25 20
33 }
34}
35
36class DNode {
37 int data;
38 DNode prev; // NEW: the node before this one
39 DNode next;
40
41 DNode(int value) {
42 data = value;
43 prev = null;
44 next = null;
45 }
46} ▶ Try it in the Programiz online compiler: tap Copy, paste it there, change public class DoublyDemo to public class Main (Programiz saves your code as Main.java, and Java needs the file name and the public class name to match), then press Run.
The if handles inserting after the last node: there is no next node, so there is no step 3. Deleting is shorter. To remove a node x that is not first or last, you need only x.prev.next = x.next; and x.next.prev = x.prev;. You do not have to search for the node before it, because x.prev already points to it.
Circular: walk the list once. In a circular list, current never becomes null, so the usual while (current != null) loop would print 10 20 30 10 20 30 … forever. Instead, print the first node, then stop when you are back at the head:
1public class CircularDemo {
2 public static void main(String[] args) {
3 Node head = new Node(10);
4 head.next = new Node(20);
5 head.next.next = new Node(30);
6 head.next.next.next = head; // 30 points back to 10
7
8 System.out.print(head.data + " "); // print the first node
9 Node current = head.next;
10 while (current != head) { // stop when back at the start
11 System.out.print(current.data + " ");
12 current = current.next;
13 }
14 System.out.println(); // 10 20 30
15 }
16}
17
18class Node {
19 int data;
20 Node next;
21
22 Node(int value) {
23 data = value;
24 next = null;
25 }
26} ▶ Try it in the Programiz online compiler: tap Copy, paste it there, change public class CircularDemo to public class Main (Programiz saves your code as Main.java, and Java needs the file name and the public class name to match), then press Run.
This loop assumes the list has at least one node. If head can be null, check that first.
How do the three kinds compare in speed? Once you have the node, inserting or deleting takes a few steps in all three kinds, however long the list is. Doubly does about twice the link work and stores one more reference per node. In return, it can go backward, and it can delete a node without searching for the one before it.
Part 8 · Your turn
Practice
Draw boxes and arrows for every problem. That is what you will do on the exam. The module's own "Check your understanding" items (Sections 3 and 4) are in the closed box below, in case you want to redo them. The "New problems" set is new. The last box is a short coding task you can do on a phone.
Show the module's practice (Sections 3 and 4)
Nodes and references
- What does this print? Explain why.
Node p = new Node(3); Node q = new Node(3); q.data = 8; System.out.println(p.data); - After these lines, how many Node objects exist? What is
first.next.data?Node first = new Node(1); Node second = new Node(2); first.next = second; Node third = first.next; - What happens when
Node n = null;is followed bySystem.out.println(n.data);?
Show the answers
- It prints 3.
newran twice, sopandqrefer to different nodes. Changingq.datadoes not affectp. - Two nodes.
thirdis just another reference to the second node.first.next.datais 2. - A NullPointerException:
nrefers to no node. Nothing catches it here, so the program stops at that line.
Insert and delete
- Start with head → 10 → 20 → 30 → null. Draw the list after these three lines. Then draw it again after
head = head.next;.Node n = new Node(15); n.next = head.next; head.next = n; - Explain in your own words:
newNode.next = current.next; - In head → 10 → 20 → 30 → 40 → null,
previousrefers to node 20. Draw the list afterprevious.next = previous.next.next;. Which node is no longer reachable? - Debugging. The list is head → 10 → 20 → 30 → null,
currentrefers to node 20, andnewNoderefers to a new node 25 (its next is null). A student wrote these lines to insert 25 after 20. Draw the result. What goes wrong?current.next = newNode; newNode.next = current.next; - Name the kind of linked list: (a) nodes have prev and next, and both ends hold null; (b) the last node's next refers to the first, and nodes have no prev; (c) a playlist on repeat with Next and Previous buttons.
Show the answers
- After the three lines: head → 10 → 15 → 20 → 30 → null (15 goes after the node head refers to). After
head = head.next;: head → 15 → 20 → 30 → null. - The new node now refers to the node that comes after
current, so the rest of the list stays reachable beforecurrentis changed. - head → 10 → 20 → 40 → null. Node 30 is no longer reachable from head.
- After
current.next = newNode;, nothing refers to 30: it is lost. ThennewNode.next = current.next;copies a reference to 25 itself, so 25 points to 25. The list reads 10 → 20 → 25 → 25 → …, and a traversal prints 25 forever. - (a) Doubly linked. (b) Circular singly linked. (c) Circular doubly linked: it repeats (circular) and goes back (prev).
New problems
- The list is head → 4 → 9 → 16 → 25 → null. Write the three values printed, one per line. After the code, which node does
headrefer to?Node current = head.next; current = current.next; System.out.println(current.data); System.out.println(current.next.data); System.out.println(head.next.data); - The list is head → 7 → 14 → null. Draw the list after these lines. Which line runs "connect the new node first"?
Node a = new Node(3); a.next = head; head = a; Node b = new Node(10); b.next = head.next.next; head.next.next = b; - The list is head → 2 → 4 → 6 → 8 → null. Draw the list after these lines. Which nodes are no longer reachable from head?
head = head.next; Node prev = head.next; prev.next = prev.next.next;
Show the answers
- 16, 25, 9.
currentstarts at 9 (head.next), then moves to 16.current.next.datais 25, andhead.next.datais still 9.headstill refers to node 4: onlycurrentmoved. - head → 3 → 7 → 10 → 14 → null. Lines 2-3 insert 3 at the beginning (new node first, then
head). Line 5,b.next = head.next.next;, connects the new node first:head.nextis 7, sohead.next.nextis 14. Then line 6 makes 7 refer to 10. - head → 4 → 6 → null. The first line drops node 2.
prevrefers to 6, andprev.next.nextis 8's next, which isnull, so 6 now ends the list. Nodes 2 and 8 are no longer reachable from head. (This works becauseprev.nextis not null.)
Your coding task: add to the end
Part 4 inserted at the beginning and after a given node. Now add a node at the end, like a new student joining the end of a line. Finish addLast in about 6 lines where it says YOUR CODE: handle the empty list first, then walk to the last node. Run it: the three printed lists must match the comments.
1class Node {
2 int data;
3 Node next;
4 Node(int value) {
5 data = value;
6 next = null;
7 }
8}
9
10public class Main {
11 // Adds a new node with this value at the END. Returns the head.
12 static Node addLast(Node head, int value) {
13 Node newNode = new Node(value);
14 // YOUR CODE:
15 // 1. If the list is empty, the new node is the whole list.
16 // 2. Otherwise, walk to the last node (its next is null)
17 // and make it refer to the new node.
18
19 return head;
20 }
21
22 static void printList(Node start) {
23 Node current = start;
24 while (current != null) {
25 System.out.print(current.data + " -> ");
26 current = current.next;
27 }
28 System.out.println("null");
29 }
30
31 public static void main(String[] args) {
32 Node head = null; // an empty list
33 head = addLast(head, 10);
34 printList(head); // expected: 10 -> null
35 head = addLast(head, 20);
36 printList(head); // expected: 10 -> 20 -> null
37 head = addLast(head, 30);
38 printList(head); // expected: 10 -> 20 -> 30 -> null
39 }
40} ▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.
Show one possible answer
1static Node addLast(Node head, int value) {
2 Node newNode = new Node(value);
3 if (head == null) {
4 return newNode;
5 }
6 Node current = head;
7 while (current.next != null) {
8 current = current.next;
9 }
10 current.next = newNode;
11 return head;
12} Output: 10 -> null, then 10 -> 20 -> null, then 10 -> 20 -> 30 -> null.
The loop checks current.next != null, not current != null like printList. It must stop on the last node, so the next line can change that node's next. With current != null, the loop walks off the end, current becomes null, and current.next = newNode; throws a NullPointerException.
The empty-list check comes first for the same reason: when head is null, there is no node to walk from. That is also why addLast returns the head. The head changes only when the list was empty, and main saves it with head = addLast(head, ...).
Part 9 · Check yourself
Self-check
Not graded. Tap an answer to see if you got it, and read why.
-
What does each node in a singly linked list store?
A node holds data and next. It has no index: it only knows which node comes next.
-
To reach the 4th node, a linked list must…
There are no indexes. Start at
headand follownextthree times. -
To insert X between B and C, which line must run first?
Connect the new node first (X → C). If B changes first, nothing points to C anymore, and the rest of the list is lost.
-
What does
previous.next = previous.next.next;do?previous.next.nextis the node two steps ahead. Pointing to it skips the node in between, so it is no longer in the list. -
After
Node b = a; b.data = 9;, what isa.data?b = acopies the reference, not the node. Both names refer to the same node, so the change shows throughatoo. -
A photo viewer with Next and Previous buttons fits which kind of linked list?
Going back needs a prev link in each node: a doubly linked list.
-
A traversal loop
while (current != null)on a circular list will…A circular list has no
nullat the end, so the condition never becomes false. It must stop when it gets back to the starting node.
Score: 0 / 7
Key takeaways
- Each node holds a value and a reference to the next node.
headrefers to the first; the last one's next isnull. Node b = a;copies the reference, not the node.- Traversal follows the links. We cannot jump to a position.
- Insertion and deletion change links, not values. Connect the new node first.
- Singly goes one way, doubly goes both, circular loops back.
- Arrays reach faster. Linked lists edit faster, once you are there.
Next lesson: Stacks.
References
- A. Bhargava, Grokking Algorithms. Manning, 2016, Chapter 2.
- M. Reid-Miller, "Singly-Linked List Class" and "Doubly-Linked Lists," 15-121 lecture slides, Carnegie Mellon University, 2020.
- Oracle, "Types, Values, and Variables," The Java Language Specification, Java SE 21, Chapter 4. docs.oracle.com
- Programiz, "Linked List Data Structure" and "Types of Linked List." programiz.com/dsa
- ITC 120 Data Structures and Algorithms Syllabus, Faculty of Computing, Engineering, and Technology, Davao Oriental State University.