CSE143 Notes 4/7/06

Introduction to Linked Lists

The story so far: we have a general purpose, low-level data structure, the array, that we can use either by itself, or even better, as the basis of a higher-level list object that has a wider repertoire of available operations (search, dynamic expansion, etc.).

Tradeoffs using arrays to implement lists:

Another way to represent a list: linked lists.

Idea: instead of using an array as the underlying data structure, we'll represent a list as a collection of objects called links (or nodes). The idea is that each link contains a reference to the data stored at its position in the list, and a reference to the next link. The end of the list is marked by a link that has an empty or "null" next-link reference, meaning that there is no next link.

Example: Draw a picture of a linked list named entrees that contains the values "chicken", "beef", "fish", and "tofu":

 

 

 

 

 

 

 

Representation in Java

There are various ways to represent links in Java. We'll use a simple, classical version. A link is an instance of a class with public data fields for the references to the item stored "in" that link and to the next link in the list. For convenience, we'll also provide a constructor to make it easy to create and initialize a new link in a single line of code.

(Encapsulation note: up to now we've made a big deal about keeping the instance variables (fields) of an object private and providing get/set methods in cases where we want to make it possible for client code to access the fields. What's different here? Why do we seem to go against our rules?

(The reason is that here we're using objects to represent a simple data structure that doesn't really have any higher-level behavior (unlike our StringList, which provided all sorts of operations, but kept the implementation details private). So our general rule still stands: instance variables and methods that don't make up the public interface of an object should be private, but for simple data structures like these links, we will make an exception.)

Anyway, here is how we'll represent a link in Java.

  public class Link {        // a single node in a linked list
    public Object item;      // data item referenced by this link
    public Link   next;      // next node in the list or null if no next node


    // construct a new Link with given item and next fields
    public Link(Object item, Link next) {
      this.item = item;
      this.next = next;
    }
    
    // construct a new Link without initializing any fields
    public Link() { }
  }

Now let's write some code to create a list called elements that contains the strings "earth", "wind", and "fire". For now, we'll write all the code explicitly (avoiding the convenience constructor with the parameters). We'll also draw a picture showing the result as we execute these statements.

 

 

 

 

 

 

 

 

 

 

Now, suppose we want to want to add the item "water" between "wind" and "fire" in the above list. First, draw the changes that need to be made in the above picture.

Next, write the Java code to implement these changes.

 

 

 

 

 

 

Next problem. Suppose we have already created a linked list named computers containing the following strings: "apple", "ibm", "compaq", "dell", "hp".

Draw the picture:

 

 

 

 

 

 

Now, suppose we want to delete the entry "compaq" from the above list. Draw in the changes in the above picture that reflect this deletion.

Now, write the Java code to make these changes.

 

 

 

 

 

Coming attractions: The goal is to use links to implement another version of our StringList with a linked list as the underlying data structure instead of an array. We'll need to explore how to do this, how to implement the list operations, and then we can take a look at the tradeoffs involved - what's faster, what's slower, etc. As we go, we'll see several list processing operations such as scanning a list, looking for particular values in a list, and so forth.