32A. Looping over Linked Lists

Some algorithms on linked lists are conveniently expressed as loops. Let's use conceptual lists to plan a loop to compute the length of a list L. We need to keep track of two variables: count (the number of values skipped over) and p (the remainder of the list). As an example, suppose L = [2, 4, 6, 8].

  p      count
[2, 4, 6, 8]    0
[4, 6, 8]    1
[6, 8]    2
[8]    3
[ ]    4

The loop ends when p is an empty list; variable count is the length of L. Notice that this loop has an invariant: at each line shown,

(length-invariant)   count + length(p) = length(L).

When p is an empty list, length(p) = 0. Substituting 0 for length(p) in (length-invariant) gives

  count + 0 = length(L).

That is, when p = [ ], count must be length(L).

Putting that plan into code gives the following definition of length(L).

  int length(ConstList L)
  {
    ConstList p      = L;
    int       count  = 0;
    
    while(p != NULL)
    {
       count++;
       p = p->tail;
    }
    return count;
  }
That can be made shorter by using a for-loop.
  int length(ConstList L)
  {
    int count  = 0;
    
    for(ConstList p = L; p != NULL; p = p->tail)
    {
       count++;
    }
    return count;
  }
Look at the for-loop heading. That is a boilerplate way to loop over all of the cells in a linked list L. Memorize it.


Exercises

  1. Using a loop, write a C++ definition of function smallest(L), which returns the smallest number in nonempty list L. Answer

  2. Using a loop, write a C++ definition of function firstEven(L), which returns the first even number in list L. If L does not contain an even number, then firstEven(L) should return −1. Answer