34C. Example: Remove a Value from a Linked List

Suppose that remove(x, L) is intended to be a destructive function that removes the first occurrence of x from list L, or does nothing if x does not occur in L. For example, if L is [2, 4, 2, 4, 5] and you perform remove(4, L), then L is changed to [2, 2, 4, 5]. The cases are as follows.

  1. If L is empty, do nothing, since x obviously does not occur in L.

  2. If L is nonempty and the head of L is equal to x, then set L to its tail. However, the cell that contains x is presumably no longer needed. So it should be deleted. Look at how it needs to work when L is [2, 4, 6] and x is 2.

  3. If L is not empty and its head is not equal to x, then remove x from the tail of L.

Expressing that in C++ yields the following definition of remove. In the second case, we need to be careful manipulating pointers to avoid cutting the branch out from under ourselves.
  void remove(int x, ListCell*& L)
  {
    if(L != NULL))
    {
      if(L->head == x)
      {
        ListCell* p = L;
        L = L->tail;
        delete p;
      }
      else
      {
        remove(x, L->tail))
      }
    }
  }