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
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
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
List Iterator
List Iterator
- To move the list position backwards, use:
Adding and Removing from a LinkedList
- The add method:
- Adds an object after the iterator
- Moves the iterator position past the new element
iterator.add("Juliet");
Adding and Removing from a LinkedList
- The remove method
- Removes and
- Returns the object that was returned by the last call to next
or previous
Adding and Removing from a LinkedList
File ListTest.java
- ListTest is a sample program that
- inserts elements into a list
- iterates through the list, adding and removing elements
- prints the list
File ListTest.java
Implementing Linked Lists
Implementing Linked Lists
- LinkedList class
- Holds a reference first to the first link
- 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
- It becomes the head of the list
- The old first link becomes the next link
Adding a New First Element
Adding a Link to the Head of a Linked List
Removing the First Element
- When the first element is removed
- The data of the first link are saved and later returned as the method
result
- The successor of the first link becomes the first link of the shorter
list
- The link will be garbage collected when there are no further references
to it
Removing the First Element
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
LinkListIterator's next Method
- 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 next Method
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 hasNext Method
- The next method should only be called when the iterator is not at the end
of the list
- The iterator is at the end
- if the list is empty (first == null)
- if there is no element after the current position (position.next ==
null)
LinkListIterator's hasNext Method
private class LinkedListIterator implements ListIterator
{ . . .
public boolean hasNext()
{
if (position == null)
return first != null;
else
return position.next != null;
}
. . .
}
LinkListIterator's remove Method
- 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:
- this call does not immediately follow a call to next
- throw an IllegalArgumentException
- Set previous reference to null
LinkListIterator's remove Method
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 set Method
LinkListIterator's add Method
- Inserts the new link after the current position
- Sets the successor of the new link to the successor of the current position
LinkListIterator's add Method
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
File ListIterator.java
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
- An ordered sequence of items that can be traversed sequentially
- Allows for insertion and removal of elements at any position
- Abstract array
- An ordered sequence of items
- 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
- A fixed number of link references need to be modified
to add or remove a link, regardless of the size of the list
- Thus, an element can be added or moved in constant time
- In big-Oh notations: O(1)
Efficiency of Linked List
- Random access
- On average n/2 elements need to be skipped
- In big-Oh notation: O(n)
Efficiency of Array List
- Adding or moving an element
- On average n/2 elements need to be moved
- In big-Oh notations: O(n)
- Random access
Efficiency of Operations for Arrays and List
Abstract Data Type Stack
- Allows insertion and removal of elements only at one end
- 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
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;
}