26B. Linked Lists


Linked lists

Our goal here is implement conceptual lists in C++. It is not possible to add notation [2, 4, 6], since we cannot add new notation to C++. But we can add functions and a type.


Representation

The first issue is how to represent the information in a list. We use a linked representation, where a linked list contains one list cell for each of its members, and the cells are linked to one another by pointers. The last cell in the linked list holds a null pointer. Here is a linked list diagram of list [2, 4, 6].

Each cell has type ListCell, defined as follows.

  struct ListCell
  {
    ListCell* tail;
    int       head;

    ListCell(int h, ListCell* t)
    {
      head = h;
      tail = t;
    }
  };


Types List and ConstList

Since a list is always a pointer to a ListCell, it is convenient to make two additional type definitions.

  typedef ListCell* List;
  typedef const ListCell* ConstList;

Function definitions

Now it is just a matter of defining the required functions and constant (emptyList) for the 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 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 = NULL;
      List Y = tail(X);
    
    Answer