CS24 Week 4 Lab: Linked Lists

Due Date: Tuesday, July 22 at 11:59:59 PM

In this lab, you will implement certain methods on linked lists. Linked lists are a fundamental data structure in programming, irrespective of the language. Not only are they very popular in their own right, they often serve as the basis for other data structures. After completing this lab, you should:

Pair Programming

You may work with a partner for this lab. If you choose a partner, both members must contribute to the same work. That is, you cannot simply divide the lab in half, as everyone is responsible for all the content. Instead, you should use a pair programming style. In pair programming, one person acts as a driver, who takes control of the keyboard. The other person acts as a navigator, who reviews what the driver writes and offers advice. Oftentimes, the driver is occupied with details of the problem (e.g., variables, control flow, etc.), whereas the navigator is concerned with bigger-picture problems (e.g., functions, design, interactions). This works well for problems which are simply too large to fit into one person's head. If you're unfamiliar with the concept of pair programming, you may wish to watch this video on the topic.

With pair programming, oftentimes it works best if both participants are of approximately the same skill level. Generally, if the disparity in skill is large, the end result is frustrating for both parties - it really only works when both parties operate at approximately the same speed. With this in mind, you should select someone of approximately the same skill level.

Reading

Chapter 3 of the Dale book is relevant, specifically with the discussion of the Unsorted List ADT. In the fifth edition, this corresponds to pages 132-138 and 158-186.

Examples

Two list implementations are provided, which we recommend looking at. You may want to open the separate files in a browser, especially for the linked list implementation. These are also provided on the main course page in zip files. You may take code from these.

  1. Array-backed lists (from here)
  2. Linked lists (from here)

Part A: Reading Questions

Step A-1: Create Directories and Copy Files

-bash-4.2$ cd
-bash-4.2$ pwd

/cs/student/yourusername

-bash-4.2$ cd cs24
-bash-4.2$ pwd

/cs/student/yourusername/cs24
-bash-4.2$ mkdir lab4
-bash-4.2$ cd lab4
-bash-4.2$ pwd

/cs/student/yourusername/cs24/lab4

Now copy over the files for this week. They are kept in the directory: /cs/student/kyledewey/cs24/labs/4

-bash-4.2$ cp /cs/student/kyledewey/cs24/labs/4/* .

Note that there is a '.' at the end of that line. cp means copy. /cs/student/kyledewey/cs24/labs/4/* means all of the files contained in the directory /cs/student/kyledewey/cs24/labs/4. The '.' means to copy from that location to the current location.

Now check to make sure the copy worked correctly:

-bash-4.2$ ls

You should see a set of files listed that will be used for this warm-up.

Step A-2: Answer Reading Questions

The file reading_questions.txt contains a series of questions you must answer. More instructions are in that file.

Part B: Start Implementing Routines on a Linked List

Step B-1: Inspect Provided Code

We have provided the following files which are relevant to this portion:

You will be spending the bulk of your time creating a new file named LinkedList.cpp, which implements the interface defined in LinkedList.h. The main function defined in main.cpp can be used along with a file containing lists (such as the one in testaddhead.txt) for testing your code. We encourage you to add your own tests; with testaddhead.txt, very little of the actual code you will write is tested.

Step B-2: Implement the Constructors for Node

Notice that the Node constructors defined in LinkedList.h have no implementation defined. Go ahead and define these in a new file, LinkedList.cpp. Be sure to add in any other necessary components to the file, such as #includes, etc. In the constructors, be sure to initialize any instance variables. If an instance variable's intended variable isn't provided, then use 0 for instance variables of type int and NULL for any instance variables of a pointer type.

Step B-3: Implement the Constructor for LinkedList

Implement the constructor for LinkedList in LinkedList.cpp. There is only one instance variable which needs to be initialized here. Think carefully about what this should be initialized to.

Step B-4: Implement printList

The printList method simply prints the contents of the list to the terminal. For example, if the list is empty, it should print [], and if the list contains the elements 1, 2, 3, then it should print [1, 2, 3]. The trick here is to traverse the list with a Node*. The provided example code should prove invaluable here.

Step B-5: Implement addHead

The addHead mutator method should add an element to the front of a list. For example, if we have the list:

[1, 2, 3]

...and we call list.addHead(0), then the resulting list should be:

[0, 1, 2, 3]

The implementation will require you to change the head field in the object, so that the head node in the list holds onto the item added along with the original head of the list.

Step B-6: Implement Stubs for Missing Methods

At this point, a variety of methods still need to be implemented, which are preventing you from being able to compile and test your code properly. Go ahead and write stubs for these remaining components, which are the most basic bits of code necessary to get through compilation. For methods that return void, these should simply have an empty body. For methods that return int, these should return 0, and for bool they should return false.

Step B-7: Midpoint: Inspect, Compile, and Run

With stubs in hand, you should be able to compile and run your code, like so:

-bash-4.2$ clang++ LinkedList.cpp main.cpp
-bash-4.2$ ./a.out testaddhead.txt

Assuming everything works with this, now would be a good point to make a backup of what you have, as with:

-bash-4.2$ cp LinkedList.cpp LinkedList.cpp.backup

If you're interested, there are far better, more streamlined ways of doing this sort of backup via revision control systems. However, these can come with a high learning curve, and they are beyond this class' materal.

Part C: Finish Implementing Routines on a Linked List

Each one of these parts is mostly independent of each other. We recommend that you test each of these thoroughly in main.cpp, perhaps even with specialized versions of main.cpp. The bulk of the work is in implementing these methods, and so the bulk of the grade is here, too.

Step C-1: Implement length

The length accessor method should return the number of nodes which are contained in the list. For testing purposes, you should be most interested in empty lists and non-empty lists.

Step C-2: Implement deleteFourth

The deleteFourth method should delete the fourth element in a linked list, if applicable. If the list contains fewer then four elements, then it should do nothing and simply return false. If the list contains four or more elements, then it should delete the fourth element and return true.

We're using a technique called the generalization technique. What we really want to learn is how to delete any node from a linked list. We're starting with implementing a specific node before generalizing to implementing any node. For this lab, you won't be implementing this more generic routine, but you'll be setup to implement it in the future.

Before you start coding, draw a picture of a linked list containing at least four nodes. Draw the linked list before you remove the fourth node and then modify the pointeres to show the linked list after you remove the fourth node. That will tell you what statements you need to write to remove the node. Then, remember that you need to delete the node's memory. You cannot delete the node's memory until after the last instruction accessing the node.

As for tests, think about the border conditions for this method. A list of length 4 is one such test, but there are several other possible tests which could be considered border conditions.

Step C-3: Implement addAmountToEach

The addAmountToEach method should add a given integer to each element of the list. For example, if we have a list:

[1, 2, 3, 1, 2, 3]

...then list.addAmountToEach(4) should result in a list:

[5, 6, 7, 5, 6, 7]

Note that this method doesn't change the structure of the list in any way, only the contents.

Step C-4: Implement the LinkedList Destructor

The destructor for linked lists must delete each node in the list. Keep in mind that once you delete a node it is gone. You cannot, for example, ask a deleted node what the next node is, since the deleted node no longer exists. If you do this, undefined behavior results. It may even appear to work, but there is absolutely no guarantee of this.

Step C-5: Implement deleteAllLessThan

This is arguably the most complex method in this assignment. This method should delete all nodes which contain a value less than a given int parameter. For example, given the list:

[7, 1, 2, 3, 4, 5, 6]

A call to list.deleteAllLessThan(3) should result in:

[7, 3, 4, 5, 6]

This method can substantially alter the list, depending on the list's contents. For example, consider the following list:

[1, 2, 3]

A call to list.deleteAllLessThan(3) would result in:

[3]

...which moves the head of the list.

Some psuedocode has been provided below which implements deleteAllLessThan(int). You do not have to adhere strictly to this if you have another method in mind for solving this problem.

def deleteAllLessThan(cutoff):
  previous = Empty
  current = head

  while current isn't Empty:
    tempNext = the node after current
    if the data in the current node is less than the cutoff:
      delete the current node
      if the current node is the head:
        current = head = tempNext
      else:
        set the next node of the previous node to be tempNext
        current = tempNext
    else:
      previous = current
      current = tempNext

Submitting your Work

First, fill out the required fields in the provided README.txt file. Once you have filled this in, you may submit everything with the following command:

-bash-4.2$ turnin lab4@cs24 README.txt LinkedList.h LinkedList.cpp main.cpp reading_questions.txt

Acknowledgements

Most content was graciously provided by Professor Diana Franklin, with formatting-related adaptations and some additional problems.