24D. Implementation of Linked Lists


Function definitions

Now it is just a matter of defining the required functions and constant (emptyList) for the list ADT.

The empty list is represented by a null pointer. Here are implementations of the head, tail and isEmpty functions and the emptyList constant. Remember that a list is a pointer, so we use -> notation to select a part of the structure to which L points.


  const List emptyList = NULL;

  int head(ConstList L)
  {
    return L->head;
  }

  List tail(List L)
  {
    return L->tail;
  }

  bool isEmpty(ConstList L)
  {
    return L == emptyList;
  }
The : operator will need to be renamed since we cannot define : to be an operator in C++. Let's use cons(h, t) for h:t. (Cons is short for construct.)
  List cons(const int h, List t)
  {
    return new ListCell(h, t);
  }


Using C++ notation

Now that you have seen how the list functions are implemented, there is really nothing wrong with using C++ notation directly. So, in C++ programs, we will feel free to write

if we choose to. Since cons(h,t) is considerably shorter then new ListCell(h, t), we will use cons.

(Note that, when using conceptual notation, we must still use head, tail, etc. You can write [ ] for the empty list.)


Building a linked list

To build up a linked list corresponding to [2, 4, 6], just notice that [2, 4, 6] = 2:4:6:[ ]. Replacing h:t by cons(h, t) gives

  List twoFourSix = cons(2, cons(4, cons(6, NULL)));


Exercises

  1. Write a statement that creates variable W of type List and makes it hold list [5, 3]. Answer

  2. What are the values of variables X, Y and k after performing the following sequence of statements? Express your answers in conceptual notation.

      List X = cons(2, cons(4, cons(6, NULL)));
      List Y = tail(X);
      int  k = head(Y);
      tail(X);
    
    Answer

  3. What happens if you do the following statements?

      List X = emptyList;
      List Y = tail(X);
    
    Answer