next up previous index
Next: Equality Up: Iteration Previous: Iteration   Index

The header node.

There are still two points to comment on. One relates to the header variable and the other relates to the possible need to reassign head.

The previous variable must always holds a reference to the node preceding the node that would be removed by a subsequent legitimate call to remove. So how should previous be initialised before any calls have been made? It is convenient, for simplicity of coding, to introduce a dummy node whose next field is the head of the list. This is done by the declaration

private ListNode header = new ListNode(null, head);
The data field is unimportant so, for definiteness, we initialise it to be the null object. Assuming the original list is $[1,2,3,\ldots]$ when the iterator method is called, the picture before either of the iterator's next or remove methods is called is shown in Figure 6.6.

Figure 6.6: The initial picture.

\begin{picture}(630,180)(-40,-70)
\put(20,20){\vector(1,0){60}}
\put(80,0){\fr...
...e$\cdots$}}
\put(240,-70){\makebox(0,0)[b]{\texttt{\small head}}}
\end{picture}

If either of the iterator's next or remove methods is called, the first call must be to next. The picture is then shown in Figure 6.7.

Figure 6.7: The picture after the first call to next.

\begin{picture}(630,180)(-40,-70)
\put(20,20){\vector(1,0){60}}
\put(80,0){\fr...
...rge$\cdots$}}
\put(-15,22){\makebox(0,0){\texttt{\small header}}}
\end{picture}

Now suppose that remove is called. Then the situation is shown in Figure 6.8.

Figure 6.8: The situation after removing the first item.

\begin{picture}(520,180)(-40,-70)
\put(20,20){\vector(1,0){60}}
\put(80,0){\fr...
...xttt{\small header}}}
\put(460,20){\makebox(0,0){\large$\cdots$}}
\end{picture}

Since we have removed the first node in the list, the head of the list has changed. The node to which it originally referred is no longer part of the list. The node at the head of the list is now the one containing the data item 2. This means that head must be reassigned. This always happens when we delete the first item in the current list. For example, we might now choose to remove the data item 2, in which case head must again be reassigned. On the other hand, once we have decided not to remove the first item in the current list, head no longer changes. All reassignments take place further down the list. This explains the code
head = header.next;
The header node is fixed throughout the iteration and its next field will always hold a reference to the first element of the list, whatever removals take place. In fact this reassignment only makes a difference if previous points to the header node, otherwise there is no way of changing header.next. It would in fact be equivalent to replace the above line of code with the conditional statement
if (previous == header) {
    head = current;
}
but the unconditional statement is simpler and possibly more efficient.

As a final comment, we observe that many implementations of linked lists use the dummy header node as a permanent feature, in order to deal with situations like this. For present purposes, it is simpler to introduce it locally as needed.


next up previous index
Next: Equality Up: Iteration Previous: Iteration   Index
Peter Williams 2005-06-07