cmput 115 - lecture 15 department of computing science university of alberta ©duane szafron 2000...

30
Cmput 115 - Lecture 15 Department of Computing Science University of Alberta ©Duane Szafron 2000 Some code in this lecture is based on code from the book: Java Structures by Duane A. Bailey or the companion structure package Revised 2/24/00 Singly-Linked Lists Singly-Linked Lists

Post on 22-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Cmput 115 - Lecture 15

Department of Computing Science

University of Alberta©Duane Szafron 2000

Some code in this lecture is based on code from the book:Java Structures by Duane A. Bailey or the companion structure package

Revised 2/24/00

Singly-Linked ListsSingly-Linked Lists

©Duane Szafron 2000

2

About This LectureAbout This Lecture

In this lecture we will learn about an implementation of the List Interface called Singly Linked List.

©Duane Szafron 2000

3

OutlineOutline

Drawing Lists and List Nodes

SinglyLinkedListElement class

SinglyLinkedList class

©Duane Szafron 2000

4

External Container DiagramsExternal Container Diagrams

We can draw an external or implementation-independent diagram of a container by just showing its elements.

For example, here is the diagram for a general container where the elements are not even ordered:

"Fred"

"Barney""Wilma"

©Duane Szafron 2000

5

Indexed Container DiagramsIndexed Container Diagrams

We can modify the diagram when the interface is more specific.

For example, here is a diagram for an indexed container.

Note that it still might be implemented as a vector or as an array.

0 1 2

"Fred" "Barney" "Wilma"

©Duane Szafron 2000

6

External List DiagramsExternal List Diagrams

Since a List is not indexed, the elements are not numbered.

However, since the elements are ordered, they must be “connected” somehow to maintain this order.

Since different implementation classes “connect” the elements differently, we do not show the connections in an external diagram.

"Fred" "Barney" "Wilma"

©Duane Szafron 2000

7

Internal List Diagrams - NodesInternal List Diagrams - Nodes

When we want to highlight a particular class implementation of the List interface, we add internal internal structurestructure.

Each element is put in a list nodenode and the nodes connect to each other with linkslinks.

The end of the list is denoted by a dot instead of a link to another node.

“Fred” “Wilma” “Barney”

“Fred” “Wilma” “Barney”

©Duane Szafron 2000

8

Complex List Node DiagramsComplex List Node Diagrams

If the elements of a list are complex objects, it is not always possible to draw the elements inside the node.

In this case, an arrow is used in the node to represent a reference to the element.

This diagram is actually more accurate since the node always contains a reference to an object instead of an object.

“Fred”8/14/1976

©Duane Szafron 2000

9

Terminology - Elements and NodesTerminology - Elements and Nodes The textbook uses the term valuevalue to refer to an object

in a list.

In these notes we use the term elementelement instead of value, since value could be confused with primitive value and the elements are objects like StringsStrings, IntegersIntegers or PersonsPersons, not primitive values.

We use the term nodenode to refer to an object that contains an element objectelement object and linkslinks to adjacent list nodes.

The book uses the term elementelement to refer to one of our nodes.

©Duane Szafron 2000

10

Singly-Linked ListsSingly-Linked Lists

In a singly-linked listsingly-linked list, each list node contains an element and a link to the “next”“next” node in the list.

Since a node contains a link to the next node, this is an example of self-referencingself-referencing of objects.

We need to define two classes to implement a singly-linked list, one for the nodesnodes and one for the listlist itself.

In the textbook’s structure package, the list node class is called SinglyLinkedListElementSinglyLinkedListElement and the list class is called SinglyLinkedListSinglyLinkedList.

©Duane Szafron 2000

11

SinglyLinkedListElement ClassSinglyLinkedListElement Class Each instance of SinglyLinkedListElementSinglyLinkedListElement represents a

single list node with two instance variablestwo instance variables.

The instance variable, datadata, is a reference to an element object.

The instance variable, nextnext, is a reference to the next node (another instance of SinglyLinkedListElement) or null if it is the last node (tailtail node).

“Fred”8/14/1976

“Wilma”10/14/1979

“Barney”3/10/1978

null

©Duane Szafron 2000

12

SinglyLinkedListElement 1SinglyLinkedListElement 1public class SinglyLinkedListElementSinglyLinkedListElement{ protected Object datadata;

protected SinglyLinkedListElement nextnext;

public SinglyLinkedListElement SinglyLinkedListElement (Object element, SinglyLinkedListElement nextNode) {

//post: initializes the node to contain the given// object and link to the given next node.

this.data = element;this.next = nextNode;

}

public SinglyLinkedListElement SinglyLinkedListElement (Object element) {//post: initializes the node to be a tail node// containing the given value.

this(element, null);}

code based on Bailey pg. 106

data next

“Wilma” next

SinglyLinkedListElement( “Wilma”, next)

“Wilma” null

SinglyLinkedListElement(“Wilma”)

©Duane Szafron 2000

13

code based on Bailey pg. 107

“Fred”8/14/1976

“Wilma”10/14/1979

“Barney”3/10/1978

null

Lastthis

SinglyLinkedListElement 2SinglyLinkedListElement 2

public SinglyLinkedListElement next( )next( ) {// post: returns the next node.

return this.next; }

public void setNext setNext (SinglyLinkedListElement next) {// post: sets the next node to be the given node

this.next = next; }

setNext (Last)

next ( )

©Duane Szafron 2000

14

SinglyLinkedListElement 2SinglyLinkedListElement 2

public SinglyLinkedListElement next ( ) {// post: returns the next node.

return this.next; }

public void setNext (SinglyLinkedListElement next) { // post: sets the next node to be the given node

this.next = next; }

public Object value ( ) {// post: returns the element in this node

return this.data; }

public void setValue (Object anObject) {// post: sets the element in this node to the given object.

this.data = anObject; }code based on Bailey pg. 107

1429

©Duane Szafron 2000

15

SinglyLinkedList ClassSinglyLinkedList Class

Each SinglyLinkedList objectSinglyLinkedList object has an instance variable, headhead, that is a reference to the first SinglyLinkedListElement object of the list.

It also maintains an int valuedint valued instance variable, countcount, that is the size of the list.

“Fred” “Wilma” “Barney”

3headcount

©Duane Szafron 2000

16

Caching the List SizeCaching the List Size

The list sizesize could be computed by traversing the list and counting nodes.

However, the size is cachedcached as an instance variable so that the size( )size( ) method can be computed faster.

The disadvantage of caching the size as an instance variable is that the instance variable must be updatedupdated each time an element is added or removed from the list.

©Duane Szafron 2000

17

List TraversalList Traversal

Many list methods will involve traversaltraversal of the list elements from the head to the tail or from the head to a particular element or location.

We use a cursor referencecursor reference for traversal.

“Fred” “Wilma” “Barney”3

cursor

“Fred” “Wilma” “Barney”3

“Fred” “Wilma” “Barney”3

“Fred” “Wilma” “Barney”3

cursor = this.head;

cursor = cursor.next;

cursor = cursor.next;

cursor = cursor.next;

cursor

cursornull

cursor

©Duane Szafron 2000

18

SinglyLinkedList - SinglyLinkedList - State and ConstructorState and Constructor

public class SinglyLinkedList implements List{

protected int count;protected SinglyLinkedListElement head;

public SinglyLinkedList() {//post: initializes the list to be empty.

this.head = null;this.count = 0;

}

code based on Bailey pg. 107

©Duane Szafron 2000

19

SinglyLinkedList - SinglyLinkedList - Store InterfaceStore Interface

/* Interface Store Methods */public int size() {//post: returns the number of elements in the list.

return this.count;} public boolean isEmpty() {// post: returns the true iff store is empty.

return this.size() == 0 // why call to size()?}public void clear() {// post: clears the list so that it contains no elements.

this.head = null;this.count = 0; // change constructor to call clear()?

}

code based on Bailey pg. 108

©Duane Szafron 2000

20

SinglyLinkedList - SinglyLinkedList - Collection Interface Collection Interface 11

/* Interface Collection Methods */public boolean containscontains (Object anObject);// pre: anObject is non-null// post: returns true iff the collection contains the // object

SinglyLinkedListElement cursorcursor;

cursor = this.head; // partial traversalwhile ((cursor != null) &&

(!cursor.value().equals(anObject)) cursor = cursor.next();return cursor != null;

}

code based on Bailey pg. 114

©Duane Szafron 2000

21

Trace of Trace of containscontains method method

“Fred” “Wilma” “Barney”

3headcount

cursor

Looking for “Barney”?

Yes!

©Duane Szafron 2000

22

SinglyLinkedList SinglyLinkedList Collection Interface 2Collection Interface 2

public void add (Object anObject) {// pre: anObject is non-null// post: the object is added to the collection. The // replacement policy is not specified

this.addToHead(anObject);}public Object remove (Object anObject);// pre: anObject is non-null// post: removes object “equal” to anObject and // returns it; otherwise returns nil

}public Iterator elements( ) {// post: return an iterator for traversing the collection// Ignore this one until textbook Chapter 8!

}code based on Bailey pg. 108

©Duane Szafron 2000

23

SinglyLinkedList - SinglyLinkedList - addToHead()addToHead()

/* Interface List Methods */public void addToHead(Object anObject) {// pre: anObject is non-null// post: the object is added to the beginning of the list

this.head = new SinglyLinkedListElement(anObject,this.head);

this.count++;}

code based on Bailey pg. 110

“Fred” “Wilma” “Barney”

3 “Pebbles”

1

1

2

2

3

3

4

©Duane Szafron 2000

24

SinglyLinkedList - SinglyLinkedList - removeFromHead()removeFromHead()

public Object removeFromHead() {// pre: list is not empty// post: removes and returns first object from the list

SinglyLinkedListElement temp;temp = this.head;this.head = this.head.next();this.count--;return temp.value();

}

code based on Bailey pg. 110

1temp

12

3

“Fred” “Wilma” “Barney”

3 23

2

©Duane Szafron 2000

25

SinglyLinkedList - SinglyLinkedList - peek() and tailPeek()peek() and tailPeek()

public Object peek ( ) {// pre: list is not empty// post: returns the first object in the list without // modifying the list

return this.head.value();}

public Object tailPeek ( ) {// pre: list is not empty// post: returns the last object in the list without // modifying the list

// left as an exercise}

code based on Bailey pg. 111

©Duane Szafron 2000

26

SinglyLinkedList - SinglyLinkedList - addToTail()addToTail()

public void addToTail (Object anObject) {// pre: anObject is non-null// post: the object is added at the end of the list

SinglyLinkedListElement temp;SinglyLinkedListElement cursor;temp = new SinglyLinkedListElement(anObject, null);

if (this.head == null) // list was empty this.head = temp;else { cursor = this.head; while (cursor.next() != null)

cursor = cursor.next(); cursor.setNext(temp); // add at end }this.count++; }

code based on Bailey pg. 113

©Duane Szafron 2000

27

Removal From Tail - ProblemRemoval From Tail - Problem

We cannot remove from the tail by traversing to the last node and removing it.

We need a reference to the second last node so we can set its “next” reference to null.

“Fred” “Wilma” “Barney”3

cursor

previous.setNext(null);

“Fred” “Wilma” “Barney”3

cursorprevious

To find the second last node, we need to traverse the list with a second cursor following the first.

null

©Duane Szafron 2000

28

SinglyLinkedList - SinglyLinkedList - removeFromTail()removeFromTail() problemproblem

cursor = this.head;while (cursor.next() != null) {

previous = cursor;cursor = cursor.next();

}previous.setNext(null);this.count--;return cursor.value();

}

1

previous

“Fred”

1 cursor1

nullcode based on Bailey pg. 113

In this case we just want to bindthis.head to null.

Check the boundaries!If the list has one node, previous is unbound

©Duane Szafron 2000

29

SinglyLinkedList - SinglyLinkedList - removeFromTail()removeFromTail()

public Object removeFromTail() {// pre: list is not empty// post: the last object in the list is removed and returned

SinglyLinkedListElement cursor;SinglyLinkedListElement previous;Assert.pre(!this.isEmpty(), “List is not empty”);cursor = this.head;previous = null;while (cursor.next() != null) { previous = cursor; cursor = cursor.next(); }if (previous == null); this.head = null;else previous.setNext(null);this.count--;return cursor.value(); }

code based on Bailey pg. 113

©Duane Szafron 2000

30

Some Principles from the TextbookSome Principles from the Textbook

8.8. When manipulating references, draw pictures.When manipulating references, draw pictures.

9. Every public method of an object should leave 9. Every public method of an object should leave the object in a consistent state.the object in a consistent state.

10. Symmetry is good.10. Symmetry is good.

11. Test the boundaries of your structures and 11. Test the boundaries of your structures and methods.methods.

principles from Bailey ch. 6