lists. the position abstract data type a positionp, which is associated with some elemente in a list...
Post on 22-Dec-2015
216 views
TRANSCRIPT
Lists
A salesman has the following schedule to visit cities in Canada: Halifax Montreal Ottawa Toronto Winnipeg Regina Edmonton Vancouver This can be represented by a vector and each element (city) can be accessed by its rank. Is there any other way to access the elements?
The answer is “yes”! Supposed I ask you to find the city in the schedule that is after Toronto and before Regina? Halifax Montreal Ottawa Toronto Winnipeg Regina Edmonton Vancouver Therefore, an element can be located (referenced) by its neighbors. In other words, in a sequence, the two neighbors of each element define a position.
The Position Abstract Data Type
The position abstract data type supports the following simple method: element(): Return the element stored at this position
Input: None; Output: Object The concept of position is similar to the concept of node in a doubly linked list. list: A container of elements that stores each element at a position and that keeps these positions arranged in a linear order.
Examples:
1. Records in a data file 2. Letters in a text file 3. Java statements in a source code file 4. Pages in a book
In a list, a position p will always be after some position q and before some position s except when p is the first or last position.
q p s
A position p, which is associated with some element e in a list S, does not change, even if the rank of e changes in S, unless we explicitly remove e (or change its neighbors). Example:
q p s
0 1 2 3 4 5 6
After the first element (rank 0) is removed.
q p s
0 1 2 3 4 5
T h e p o s it io n p d o e s n o t c h a n g e e v e n if w e re p la c e o r sw a p th e e le m e n t e s to re d a t p w ith a n o th e r e le m e n t. E x a m p le : T h e e le m e n t a t p o s it io n p is “ T o ro n to ”
q p s
0 1 2 3 4 5
e
6
T o ro n to
P o s it io n p d o e s n o t c h a n g e if w e c h a n g e th e e le m e n t to “ O tta w a ” :
q p s
0 1 2 3 4 5
e
6
O tta w a
I f w e s w a p e l e m e n t s , p o s i t i o n p d o e s n o t c h a n g e :
q p s
0 1 2 3 4 5
e
6
T o r o n t o
q p s
0 1 2 3 4 5
e
6
O t t a w aO t t a w a
A f t e r t h e s w a p p i n g :
q p s
0 1 2 3 4 5
e
6
T o r o n t o
q p s
0 1 2 3 4 5
e
6
O t t a w a
The List Abstract Data Type
The list abstract data type supports the following methods for a list S:
first(): Return the position of the first element of S; an error occurs if S is empty. Input: None; Output: Position
last(): Return the position of the last element of S; an error occurs if S is empty. Input: None; Output: Position
isFirst(p): Return a boolean value indicating whether the given position is the first one in the list. Input: Position; Output: Boolean
isLast(p): Return a boolean value indicating whether the given position is the last one in the list. Input: Position; Output: Boolean
before(p): Return the position of the element of S preceding the one at position p; an error occurs if p is the first position. Input: Position; Output: Position
after(p): Return the position of the element of S following the one at position p; an error occurs if p is the last position. Input: Position; Output: Position
The list ADT also supports the following methods: replaceElement(p,e): Replace the element at position p with e, returning
the element formerly at position p. Input: Position p and object e; Output: Object
swapElements(p,q) Swap the elements stored at position p and q, so that the element that is at position p moves to position q and the element that is at position q moves to position p. Input: Two positions; Output: None
insertFirst(e) Insert a new element e into S as the first element. Input: Object e; Output: Position of the newly inserted element e.
insertLast(e) Insert a new element e into S as the last element. Input: Object e; Output: Position of the newly inserted element e.
insertBefore(p,e): Insert a new element e into S before position p in S; an error occurs if p is the first position. Input: Position p and object e; Output: Position of the newly inserted element e.
insertAfter(p,e): Insert a new element e into S after position p in S; an error occurs if p is the last position. Input: Position p and object e; Output: Position of the newly inserted element e.
remove(p): Remove from S the element at position p. Input: Position; Output: The removed element.
This table shows a series of operations for an initially empty list S. Operation Output S insertFirst(8) p1(8) (p1(8)) inserAfter(p1,5) p2(5) (p1(8), p2(5)) insertBefore(p2,3) p3(3) (p1(8),p3(3),p2(5)) insertFirst(9) p4(9) (p4(9),p1(8),p3(3),p2(5)) before(p3) p1(8) (p4(9),p1(8),p3(3),p2(5)) last() p2(5) (p4(9),p1(8),p3(3),p2(5)) remove(p4) 9 (p1(8),p3(3),p2(5)) swapElements(p1,p2) - (p1(5),p3(3),p2(8)) replaceElement(p3,7) 3 (p1(5),p3(7),p2(8)) insertAfter(first(),2) p5(2) (p4(5),p(2),p3(7),p2(8))
Invalid Positions
There are a few reasons that cause a position p to be invalid:
p is a null position p has been deleted from the list p is a position of a different list
We use an exception called InvalidPositionException to handle such errors.
Doubly Linked List Implementation
Recall that nodes in a doubly linked list are similar to position: They have a reference to the next node and another reference to the previous node. Therefore, it is natural to use doubly linked list to implement a list abstract data type.
public class DNode implements Position { private DNode next, prev; private Object element; public DNode( DNode newPrev, DNode newNext, Object elem ){ prev = newPrev; next = newNext; element = elem; } public Object element() throws InvalidPositionException { if(( prev == null ) && ( next == null )) throw new InvalidPositionException(
"Position is not in a list!" ); return element; } public DNode getNext() { return next; } public DNode getPrev() { return prev; }
public void setNext( DNode newNext ) { next = newNext; } public void setPrev( DNode newPrev ) { prev = newPrev; } public void setElement( Object newElement ) { element = newElement; } }
Dnode element(){…}; getNext(){…}; getPrev(){…}; setNext(){…}; setPrev(){…}; setElement(){…};
Interface Hierarchy for Positions
impl.
Position element();
Algorithms insertAfter( p, e ): create a new node v assign element e to node v set link from node v to its previous node p set link from node v to its next node q set link from node p to node v set link from node q to node v return node v
B e f o r e i n s e r t A f t e r ( ) :
h e a d e r
B a l t i m o r e R o m e S e a t t l e
t r a i l e r
A n e w n o d e i s c r e a t e d :
h e a d e r
B a l t i m o r e R o m e S e a t t l e
t r a i l e r
v
se t l in k f ro m n o d e v to its p re v io u s n o d e p s e t l in k f ro m n o d e v to its n e x t n o d e q
h ea d e r
B a ltim o re
e
S ea tt le
tr a ile r
T o ro n to
R o m e
p
v
q
se t l in k f ro m n o d e p to n o d e v s e t l in k f ro m n o d e q to n o d e v
h ea d e r
B a ltim o re
e
S ea tt le
tra ile r
T o ro n to
R o m e
p
v
q
A f t e r i n s e r t A f t e r ( ) :
h e a d e r
B a l t i m o r e
e
S e a t t l e
t r a i l e r
T o r o n t o R o m e
p v q
remove( p ): /* assume node p’s next node is n and its previous node is q */ save element e of node p to a variable t set link from node q to node n set link from node n to node q set the next link of node p to null set the prev link of node p to null return t
B e f o r e r e m o v e ( p ) :
h e a d e r
B a l t i m o r e S e a t t l e
t r a i l e r
T o r o n t o R o m e
p
s a v e e le m e n t e o f n o d e p to a v a r ia b le t
h e a d e r
B a l t im o r e S e a t t l e
t r a i l e r
T o r o n to R o m e
p
t
set link from node q to node n set link from node n to node q
header
Baltimore Seattle
trailer
Toronto
Rome
p
t
nq
set the next link of node p to null set the prev link of node p to null
header
Baltimore Seattle
trailer
Toronto
Rome
p
t
nq
A f t e r r e m o v e ( ) :
h e a d e r
B a l t i m o r e S e a t t l e
t r a i l e r
T o r o n t o
nq
public interface List {/** Returns the number of elements in this list. */ public int size(); /** Returns whether the list is empty. */ public boolean isEmpty(); /** Returns the first node in the list. */ public Position first(); /** Returns the last node in the list. */ public Position last(); /** Returns the node after a given node in the list. */ public Position next(Position p) throws InvalidPositionException, BoundaryViolationException; /** Returns the node before a given node in the list. */ public Position before(Position p) throws InvalidPositionException, BoundaryViolationException;
public Position after(Position p) throws InvalidPositionException, BoundaryViolationException;
/** Inserts an element at the front of the list. */ public Position insertFirst(Object e); /** Inserts and element at the back of the list. */ public Position insertLast(Object e); /** Inserts an element after the given node in the list. */ public Position insertAfter(Position p, Object e) throws InvalidPositionException; /** Inserts an element before the given node in the list. */ public Position insertBefore(Position p, Object e) throws InvalidPositionException; /** Removes a node from the list. */ public Object remove(Position p) throws InvalidPositionException; /** Replaces the element stored at the given node. */ public Object replace(Position p, Object e)
throws InvalidPositionException;
public void swapElements( Position a, Position b )throws InvalidPositionException;
}
class InvalidPositionException extends Exception { public InvalidPositionException() {super();} public InvalidPositionException(String s) { super(s); }}
class EmptyContainerExeption extends Exception { public EmptyContainerExeption() {super();} public EmptyContainerExeption(String s) { super(s); }}
class BoundaryViolationExeption extends Exception { public BoundaryViolationExeption() {super();} public BoundaryViolationExeption(String s) { super(s); }}
Class NodeList
public class NodeList implements List { protected int numElts; protected DNode header, trailer; public NodeList() { numElts = 0; header = new DNode( null, null, null ); trailer = new DNode( header, null, null ); header.setNext( trailer ); trailer.setPrev( header ); }
header trailer
protected DNode checkPosition( Position p ) throws InvalidPositionException { if( p == null ) throw new InvalidPositionException( "Null position passed to NodeList." ); if( p == header ) throw new InvalidPositionException( "The header node is not a valid position." ); if( p == trailer ) throw new InvalidPositionException( "The trailer node is not a valid position." ); try { DNode temp = ( DNode )p; if(( temp.getPrev() == null ) || ( temp.getNext() == null )) throw new InvalidPositionException( "Position does not belong to a valid NodeList." ); return temp; }
catch( ClassCastException e ) { throw new InvalidPositionException( "Position is of wrong type for this container." );
} }
public int size() { return numElts; } public boolean isEmpty() { return( numElts < 1 ); } public boolean isFirst( Position p ) throws InvalidPositionException { DNode v = checkPosition(p); return v.getPrev() == header; } public Position first() throws EmptyContainerException { if( isEmpty() ) throw new EmptyContainerException( "List is empty" ); return header.getNext(); } public Position last() throws EmptyContainerException { if( isEmpty() ) throw new EmptyContainerException( "List is empty" ); return trailer.getPrev(); }
public Position before( Position p ) throws InvalidPositionException, BoundaryViolationException { DNode v = checkPosition( p ); DNode prev = v.getPrev(); if( prev == header ) throw new BoundaryViolationException( "Cannot advance past the beginning of the list" ); return prev; }
public Position insertBefore( Position p, Object element ) throws InvalidPositionException { DNode v = checkPosition( p ); numElts++; DNode newNode = new DNode( v.getPrev(), v, element ); v.getPrev().setNext( newNode ); v.setPrev( newNode ); return newNode; }
header trailerv = p
element
newNode
public Position insertFirst( Object element ) { numElts++; DNode newNode = new DNode( header, header.getNext(), element ); header.getNext().setPrev( newNode ); header.setNext( newNode ); return newNode; }
header trailer
element
newNode
public Object remove( Position p ) throws InvalidPositionException { DNode v = checkPosition( p ); numElts--; DNode vPrev = v.getPrev(); DNode vNext = v.getNext(); vPrev.setNext( vNext ); vNext.setPrev( vPrev ); Object vElem = v.element(); v.setNext( null ); v.setPrev( null ); return vElem; }
header trailer
v = p
vPrev
vElem
vNext
public Object replaceElement( Position p, Object element ) throws InvalidPositionException { DNode v = checkPosition( p ); Object oldElt = v.element(); v.setElement( element ); return oldElt; } public void swapElements( Position a, Position b ) throws InvalidPositionException { DNode pA = checkPosition( a ); DNode pB = checkPosition( b ); Object temp = pA.element(); pA.setElement( pB.element() ); pB.setElement( temp ); }
List first(); last(); isFirst(); isLast(); before(); after(); replaceElement(); swapElement(); insertFirst(); insertLast();
NodeList … ….
Interface Hierarchy for Lists
impl.
Data Structure Exercises 8.1
Generate a list containing 10 elements:0, 1, …, 9.
Note that some methods specified in theList interface (such as after(),insertAfter()) are missing. You have toprovide the implementation of these methodsin the NodeList class.