lists. the position abstract data type a positionp, which is associated with some elemente in a list...

47
Lists A salesm an hasthe follow ing schedule to visitcitiesin Canada: Halifax M ontreal Ottawa Toronto Winnipeg Regina Edm onton V ancouver Thiscan be represented by a vectorand each elem ent(city)can be accessed by itsrank. Isthere any otherw ay to accessthe elem ents?

Post on 22-Dec-2015

216 views

Category:

Documents


0 download

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.

List ADT position

Doubly linked list DNode

Doubly Linked List Implementation

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 interface Position {

Object element();

}

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

assign element e to node v

header

Baltimore Rome

v

trailer

Toronto

Seattle

e

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.

public class GenerateList {

public static void main(String args[]) {Position temp;NodeList x = new NodeList();for (int i = 0; i < 10; i++) { temp = x.insertFirst(new Integer(i)); try {

System.out.println(((Integer)(temp.element())).intValue());

}catch (InvalidPositionException e){}

}}

}