Walking a List: The cur = head, while (cur != null) Idiom
Try This First
You have a three-element list: head -> [10] -> [20] -> [30] -> null. Starting with Node<Integer> cur = head;, you enter the loop and print cur.data, then write cur = cur.next;. How many times does the print statement run before the loop ends?
Reveal
Three times. cur visits the node holding 10, then 20, then 30. After advancing from 30, cur becomes null and the condition cur != null is false, so the loop exits.
What You Need To Walk In With
- A linked list in this course stores a reference called
headthat points to the first node (or isnullfor an empty list). - Each node holds a
datafield of typeTand anextreference pointing to the following node (ornullat the end of the chain). - The traversal idiom initializes a local pointer
curtoheadand advances it one step per iteration untilcurisnull. - On an empty list (
head == null), the loop body never executes because the condition fails immediately. - For a list of N elements the loop body executes exactly N times (source: Liang 10e Ch 24).
How It Works
The traversal idiom has three parts: initialize, test, and advance.
Node<T> cur = head; // 1. Start at the first node (or null)
while (cur != null) { // 2. Stop when there is no more node
System.out.println(cur.data);
cur = cur.next; // 3. Move one step toward the end
}
A rough picture of what happens on a two-element list:
head
|
[A | next] -> [B | next] -> null
^
cur (iteration 1: prints A, then cur = cur.next)
^
cur (iteration 2: prints B, then cur = cur.next => null)
^
cur == null => loop exits
After the loop, cur is guaranteed to be null. The original head reference is untouched because cur is a local copy.
The for-loop form is equivalent and more compact, though Steiner’s published 211 labs use the while form:
for (Node<T> cur = head; cur != null; cur = cur.next) {
System.out.println(cur.data);
}
Both forms visit every node in order and terminate cleanly on an empty list.
Worked Example: Predict, Then Check
Consider this list and code fragment:
// List contains: 5 -> 12 -> 7 -> null
Node<Integer> cur = head;
int count = 0;
while (cur != null) {
if (cur.data > 8) count++;
cur = cur.next;
}
System.out.println(count);
What does the program print?
Reveal
It prints 2. The loop visits three nodes. Only 12 and... wait, 12 > 8 (yes) and 7 > 8 (no) and 5 > 8 (no). So count increments once for 12. The answer is 1.
Trace carefully: 5 is not > 8, 12 is > 8, 7 is not > 8. count reaches 1.
A Common Mistake
It is tempting to write while (cur.next != null) instead of while (cur != null). That change skips the last node in the list because the condition becomes false one step too early (when cur points to the final node, cur.next is already null). Worse, on an empty list where head == null, the condition tries to evaluate null.next, which throws a NullPointerException immediately. The fix is always to test cur itself: while (cur != null). That condition handles both the empty-list case and ensures every node, including the last one, is processed. (Source: Liang 10e Ch 24)
Go Deeper (optional)
This traversal runs in O(N) time because each of the N nodes is visited exactly once. That cost appears in every method that needs to inspect all elements (searching, counting, building a string representation). If you later study the dummy-head variant, the loop body does not change; the only difference is that the loop starts at head.next rather than head. For now, the no-dummy-head form is the course standard, and every method special-cases an empty list by checking head == null before entering the traversal.
Check Yourself
Close the notes and answer each one from memory, then reveal it. Pulling an idea back from memory is one of the strongest ways to make it stick.
Check your understanding
Which statement correctly initializes the traversal idiom for a no-dummy-head singly linked list?
For an empty list (head == null), how many times does the loop body in ‘Node<T> cur = head; while (cur != null) { ... cur = cur.next; }’ execute?
Why does ‘while (cur.next != null)’ cause a NullPointerException on an empty list?
Trace: list is [3] -> [6] -> null. Code: Node<Integer> cur = head; int sum = 0; while (cur != null) { sum += cur.data; cur = cur.next; } What is sum after the loop?
Which of the following is functionally equivalent to the while-form traversal ‘Node<T> cur = head; while (cur != null) { use(cur); cur = cur.next; }’?