|
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 ListCell* emptyList = NULL; int head(const ListCell* L) { return L->head; } ListCell* tail(ListCell* L) { return L->tail; } bool isEmpty(const ListCell* 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.)
ListCell* cons(int h, ListCell* t) { return new ListCell(h, t); }
When we discuss list in conceptual terms, we must use conceptual notation. But now that you have seen how the list functions are implemented, there is nothing wrong with using C++ notation directly in a C++ program. You can write
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
ListCell* twoFourSix = cons(2, cons(4, cons(6, NULL)));
Pay attention to types. An attempt to compute [1,2] by
ListCell* oneTwo = cons(1,2);cannot be right because the second parameter of cons is required to be a list, not an integer. A list with n members needs n list cells. Since cons creates one list cell, you need to use cons twice to create a list of length 2.
Write a statement that creates variable W of type ListCell* and makes it hold list [5, 3]. Answer
What are the values of variables X, Y and k after performing the following sequence of statements? Express your answers in conceptual notation.
ListCell* X = cons(2, cons(4, cons(6, NULL))); ListCell* Y = tail(X); int k = head(Y); tail(X);Answer
What happens if you do the following statements?
ListCell* X = emptyList; ListCell* Y = tail(X);Answer
|