CHAPTER 19
An Introduction to Data
Structures
CHAPTER GOALS
• To learn how to use linked lists provided in the standard library
• To be able to use iterators to transverse linked lists
• To understand the implementation of linked lists
• To distinguish between abstract and concrete data types
• To know the efficiency of fundamental operations of lists and arrays
• To become familiar with the stack and queue types
Linked List
• A linked list consists of a number of links, each of which has a reference to the next link.
• Adding and removing elements in the middle of a linked list is efficient.
• Visiting the elements of a linked list in sequential order is efficient
• Random access is not efficient
Inserting an Element into a Linked List
Java's LinkedList class
• Easy access to first and last elements with methods
o void addFirst(Object obj) o void addLast(Object obj) o Object getFirst()
o Object getSecond() o Object removeFirst() o Object removeLast()
ListIterator
• List iterator gives access to elements inside a linked list
• ListIterator protects the linked list while giving access
• ListIterator encapsulates a position anywhere in the linked list
A List Iterator
Conceptual View of the ListIterator
List Iterator
• Think of an iterator as pointing between two links
List Iterator
• The listIterator method of the
LinkedList class gets a list iterator
LinkedList list = . . .
ListIterator iterator = list.listIterator();
List Iterator
• The next method moves the iterator
iterator.next();
• next throws a NoSuchElementException if you are already past the end of the list
List Iterator
• hasNext returns true if there is a next element
if (iterator.hasNext()) iterator.next();
List Iterator
• The next method returns the object of the link that it is passing
while iterator.hasNext() {
Object obj = iterator.next();
//do something with the object }
List Iterator
• To move the list position backwards, use:
o hasPrevious o previous
Adding and Removing from a LinkedList
• The add method:
o Adds an object after the iterator
o Moves the iterator position past the new element
iterator.add("Juliet");
Adding and Removing from a LinkedList
• The remove method:
o Removes and
o Returns the object that was
returned by the last call to next or
previous
Adding and Removing from a LinkedList
• This loop removes all objects that fulfill a certain condition
while (iterator.hasNext()) {
Object obj = iterator.next();
if (obj fulfills condition) iterator.remove();
}
File ListTest.java
• ListTest is a sample program that
o inserts elements into a list
o iterates through the list, adding and removing elements
o prints the list
File ListTest.java
01: import java.util.LinkedList;
02: import java.util.ListIterator;
03:
04: /**
05: A program that demonstrates the LinkedList class 06: */
07: public class ListTest 08: {
09: public static void main(String[] args) 10: {
11: LinkedList staff = new LinkedList();
12: staff.addLast("Dick");
13: staff.addLast("Harry");
14: staff.addLast("Romeo");
15: staff.addLast("Tom");
16:
17: // | in the comments indicates the iterator position
18:
19: ListIterator iterator = staff.listIterator(); // |DHRT 20: iterator.next(); // D|HRT
21: iterator.next(); // DH|RT 22:
23: // add more elements after second element 24:
25: iterator.add("Juliet"); // DHJ|RT 26: iterator.add("Nina"); // DHJN|RT 27:
28: iterator.next(); // DHJNR|T 29:
30: // remove last traversed element 31:
32: iterator.remove(); // DHJN|T 33:
34: // print all elements 35:
36: iterator = staff.listIterator();
37: while (iterator.hasNext())
38: System.out.println(iterator.next());
39: } 40: }
Implementing Linked Lists
• LinkedList class has a private inner class Link
class LinkedList {
private class Link {
public Object data;
public Link next;
} }
Implementing Linked Lists
• LinkedList class
o Holds a reference first to the first link
o Has a method to get the first element
Implementing Linked Lists
class LinkedList {
public LinkedList() {
first = null;
}
public Object getFirst() {
if (first == null)
throw new NoSuchElementException(); return first.data;
}
. . .
private Link first;
}
Adding a New First Element
• When a new link is added to the list
o It becomes the head of the list
o The old first link becomes the next link
Adding a New First Element
• The addFirst method
class LinkedList {
. . .
public void addFirst(Object obj) {
Link newLink = new Link(); newLink.data = obj;
newLink.next = first;
first = newLink;
} ...
}
Adding a Link to the Head of a
Linked List
Removing the First Element
• When the first element is removed
o The data of the first link are saved and later returned as the method result
o The successor of the first link becomes the first link of the shorter list
o The link will be garbage collected when there are no further references to it
Removing the First Element
• The removeFirst method
class LinkedList { . . .
public Object removeFirst() {
if (first == null)
throw new NoSuchElementException();
Object obj = first.data;
first = first.next;
return obj;
} . . . }
Removing the First Link from a Linked List
LinkedListIterator
• Private inner class of LinkedList
• Implements a simplified ListIterator
interface
• Has access to the first field and private
Link class
LinkedListIterator
The LinkListIterator class
class LinkedList { . . .
public ListIterator listIterator() {
return new LinkedListIterator();
}
private class LinkedListIterator implements ListIterator {
public LinkedListIterator() {
position = null;
previous = null;
}
. . .
private Link position;
private Link previous;
} . . . }
LinkListIterator's
nextMethod
• position reference is advances to
position.next
• Old position is remembered as previous
• If the iterator points before the first
element of the list, then the old position is
null and position must be set to first
LinkListIterator's
nextMethod
private class LinkedListIterator implements ListIterator { . . .
public Object next() {
if (!hasNext())
throw new NoSuchElementException();
previous = position; // remember for remove if (position == null)
position = first;
else
position = position.next;
return position.data;
}
. . . }
LinkListIterator's
hasnextMethod
• The next method should only be called when the iterator is not at the end of the list
• The iterator is at the end
o if the list is empty (first == null)
o if there is no element after the current position (position.next == null)
LinkListIterator's
hasnextMethod
private class LinkedListIterator implements ListIterator
{
. . .
public boolean hasNext() {
if (position == null)
return first != null;
else
return position.next != null;
}
. . . }
LinkListIterator's
removeMethod
• If the element to be removed is the first element, call
removeFirst
• Otherwise, the link proceeding the element to be
removed needs to have its next reference updated to skip the removed element
• If the previous reference is null:
o this call does not immediately follow a call to
next
o throw an IllegalArgumentException
• Set previous reference to null
LinkListIterator's
removeMethod
private class LinkedListIterator implements ListIterator { . . .
public void remove() { if (position == first)
{
removeFirst();
position = first;
} else
{
if (previous == null)
throw new IllegalStateException();
previous.next = position.next;
position = previous;
}
previous = null;
} . . . }
Removing a Link From the Middle of a Linked List
LinkListIterator's
setMethod
• Changes the data stored in the previously visited element
• The set method
private class LinkedListIterator implements ListIterator
{ . . .
public void set(Object obj) {
if (position == null)
throw new NoSuchElementException();
position.data = obj;
}
. . . }
LinkListIterator's
addMethod
• Inserts the new link after the current position
• Sets the successor of the new link to the successor of the current position
LinkListIterator's
addMethod
private class LinkedListIterator implements ListIterator { . . .
public void add(Object obj) {
if (position == null) {
addFirst(obj);
position = first;
} else {
Link newLink = new Link();
newLink.data = obj;
newLink.next = position.next;
position.next = newLink;
position = newLink;
}
previous = null;
}
. . . }
Adding a Link to the Middle of a Linked List
File LinkedList.java
001: import java.util.NoSuchElementException;
002:
003: /**
004: A linked list is a sequence of links with efficient 005: element insertion and removal. This class 006: contains a subset of the methods of the standard 007: java.util.LinkedList class.
008: */
009: public class LinkedList 010: {
011: /**
012: Constructs an empty linked list.
013: */
014: public LinkedList() 015: {
016: first = null;
017: }
018:
019: /**
020: Returns the first element in the linked list.
021: @return the first element in the linked list 022: */
023: public Object getFirst() 024: {
025: if (first == null)
026: throw new NoSuchElementException();
027: return first.data;
028: } 029:
030: /**
031: Removes the first element in the linked list.
032: @return the removed element 033: */
034: public Object removeFirst() 035: {
036: if (first == null)
037: throw new NoSuchElementException();
038: Object obj = first.data;
039: first = first.next;
040: return obj;
041: } 042:
043: /**
044: Adds an element to the front of the linked list.
045: @param obj the object to add 046: */
047: public void addFirst(Object obj) 048: {
049: Link newLink = new Link();
050: newLink.data = obj;
051: newLink.next = first;
052: first = newLink;
053: } 054:
055: /**
056: Returns an iterator for iterating through this list.
057: @return an iterator for iterating through this list
058: */
059: public ListIterator listIterator() 060: {
061: return new LinkedListIterator();
062: } 063:
064: private Link first;
065:
066: private class Link 067: {
068: public Object data;
069: public Link next;
070: } 071:
072: private class LinkedListIterator implements ListIterator 073: {
074: /**
075: Constructs an iterator that points to the front 076: of the linked list.
077: */
078: public LinkedListIterator() 079: {
080: position = null;
081: previous = null;
082: } 083:
084: /**
085: Moves the iterator past the next element.
086: @return the traversed element 087: */
088: public Object next() 089: {
090: if (!hasNext())
091: throw new NoSuchElementException();
092: previous = position; // remember for remove 093:
094: if (position == null) 095: position = first;
096: else
097: position = position.next;
098:
099: return position.data;
100: } 101:
102: /**
103: Tests if there is an element after the iterator 104: position.
105: @return true if there is an element after the iterator 106: position
107: */
108: public boolean hasNext() 109: {
110: if (position == null) 111: return first != null;
112: else
113: return position.next != null;
114: } 115:
116: /**
117: Adds an element before the iterator position
118: and moves the iterator past the inserted element.
119: @param obj the object to add 120: */
121: public void add(Object obj) 122: {
123: if (position == null) 124: {
125: addFirst(obj);
126: position = first;
127: } 128: else 129: {
130: Link newLink = new Link();
131: newLink.data = obj;
132: newLink.next = position.next;
133: position.next = newLink;
134: position = newLink;
135: }
136: previous = null;
137: }
138:
139: /**
140: Removes the last traversed element. This method may 141: only be called after a call to the next() method.
142: */
143: public void remove() 144: {
145: if (position == first) 146: {
147: removeFirst();
148: position = first;
149: } 150: else 151: {
152: if (previous == null)
153: throw new IllegalStateException();
154: previous.next = position.next;
155: position = previous;
156: }
157: previous = null;
158: } 159:
160: /**
161: Sets the last traversed element to a different 162: value.
163: @param obj the object to set 164: */
165: public void set(Object obj) 166: {
167: if (position == null)
168: throw new NoSuchElementException();
169: position.data = obj;
170: } 171:
172: private Link position;
173: private Link previous;
174: } 175: }
File ListIterator.java
01: import java.util.NoSuchElementException;
02:
03: /**
04: A list iterator allows access of a position in a linked list. This interface contains a subset of the methods of the 05: standard java.util.ListIterator interface. The methods for
06: backward traversal are not included.
07: */
08: public interface ListIterator 09: {
10: /**
11: Moves the iterator past the next element.
12: @return the traversed element 13: */
14: Object next();
15:
16: /**
17: Tests if there is an element after the iterator
18: position.
19: @return true if there is an element after the iterator 20: position
21: */
22: boolean hasNext();
23:
24: /**
25: Adds an element before the iterator position 26: and moves the iterator past the inserted element.
27: @param obj the object to add 28: */
29: void add(Object obj);
30:
31: /**
32: Removes the last traversed element. This method may 33: only be called after a call to the next() method.
34: */
35: void remove();
36:
37: /**
38: Sets the last traversed element to a different 39: value.
40: @param obj the object to set 41: */
42: void set(Object obj);
43: }
Abstract Data Types
• Abstract data type defines the
fundamental operations on the data
• Abstract data type does not specify an implementation
Abstract Data Types
• Abstract list
o An ordered sequence of items that can be traversed sequentially
o Allows for insertion and removal of elements at any position
• Abstract array
o An ordered sequence of items
o Allows for random access by specifying an integer index
An Abstract View of a Linked
List
A Concrete View of a Linked
List
An Abstract View of an Array
List
A Concrete View of an Array
List
Fundamental Operations on Array List
public class ArrayList {
public Object get(int index) {. . . }
public void set(int index, Object value) {. . . }
}
Fundamental Operations on Linked List
public class LinkedList {
public ListIteratior listIterator() {. . . } . . .
}
public interface ListIteratior {
Object next();
boolean hasNext();
void add(Object value);
void remove();
void set(Object value);
. . . }
Efficiency of Linked List
• Adding or removing an element
o A fixed number of link references need to be modified
to add or remove a link, regardless of the size of the list
o Thus, an element can be added or moved in constant time
o In big-Oh notations: O(1)
Efficiency of Linked List
• Random access
o On average n/2 elements need to be skipped
o In big-Oh notation: O(n)
Efficiency of Array List
• Adding or moving an element
o On average n/2 elements need to be moved o In big-Oh notations: O(n)
• Random access
o In big-Oh notation: O(1)
Efficiency of Operations for Arrays and List
Abstract Data Type Stack
• Allows insertion and removal of elements only at one end
o Traditionally called the top of the stack
• New items are added to the top of the stack
• Items are removed at the top of the stack
• Called last in, first out or LIFO order
• Think of a stack of books
A Stack of Books
• A stack can be visualized as a stack of books.
• You place books on top and remove from the top.
A Stack of Books
Abstract Data Type Stack
• The Stack class is a concrete
implementation of a stack in the Java library
• The Stack class uses an Object[] to implement a stack
Abstract Data Type Stack
• Sample code to use the Stack class
Stack s = new Stack();
s.push("A");
s.push("B");
s.push("C");
//the following loop prints C, B, A int i = s.size();
while (i > 0) {
System.out.println(s.pop());
i--;
}
Abstract Data Type Queue
• Items added to one end of the queue (the tail)
• Items removed from the other end (the head)
• Called first in, first out or FIFO order
• Think of a queue of people
A Queue
• A Queue can be visualized as a queue of people.
• People join the tail of the queue and wait until they reach the head.
A Queue
Abstract Data Type Queue
• No implementing class in the Java library
• Can be implemented using a linked list
A Queue Implementation
public class Queue {
/**
Constructs an empty queue */
public Queue() {
list = new LinkedList();
}
/**
Adds an item to the tail of the queue @param x the item to add
*/
public void add(Object x) {
list.addLast(x);
} /**
Removes an item from the head of the queue @return the removed item
*/
public Object remove() {
return list.removeFirst();
} /**
Gets the number of items in the queue @return the size
*/
public int size() {
return list.size() }
private LinkedList list;
}