cmput 115 - lecture 15 department of computing science university of alberta ©duane szafron 2000...
Post on 22-Dec-2015
213 views
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