Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lists We’ve seen an array-based list implementation, the ArrayList.

Similar presentations


Presentation on theme: "Lists We’ve seen an array-based list implementation, the ArrayList."— Presentation transcript:

1 Lists We’ve seen an array-based list implementation, the ArrayList.
Advantage of an array-based implementation: fast access to a specific index typically less space usage than other options Disadvantage of an array-based implementation: can be expensive to insert items resizing is an expensive operation

2 Amortization Resizing of array-based data structures involves a tradeoff: many insertions (as in our Bag) are very efficient since no allocation of space is required (an array is allocated as a big block of memory) some insertions (as in our Bag) are very expensive since resizing must take place

3 Linked List A linked list is a list implementation which spreads out the cost of space allocation evenly to all insertions. Each insertion involves allocation of space

4 Advantages/Disadvantages
predictable cost of insertion efficient insertion at any point in structure Disadvantages extra space required to store links inefficient indexing

5 Comparison of storage A pair has a first and a second element
When pairs are used to construct lists, the first is called the “head” or the “car” the second is called the “tail”, “rest” or “cdr” the pair is called a “cons cell” or simply a “cons”.

6 Linked list implementations
Textbook discusses a typical linked list implementation java.util.LinkedList is another typical implementation These implementations have procedural, not object-oriented, roots.

7 Traditional implementations
provide a large number of methods – making it difficult to reuse if less functionality is desired; provide no means, beyond inheritance, to extend functionality to suit a specific situation; and adding functionality requires knowledge of internal structure of the list.

8 So… These implementations are inflexible, and do not exhibit good OO design. In lecture we will discuss a state-based list implementation which can be easily extended with new functionality.

9 Variant/Invariant decomposition
Design principle which leads to cohesive and decoupled components That which is invariant is put into one component Variant properties/behaviors are factored out into separate components

10 a list = a Linear Recursive Structure (LRS or LRStruct)
What is a list? the empty list is a list a pair whose tail is a list is itself a list This is a recursive definition! (1) is called the base case, and (2) is called the recursive case. Note that traditional implementations do not follow this precise definition of what a list is: many have no explicit representation of an empty list none are recursive on the list; instead they recurse on a list node This has implications for how the structure can support extension (see Visitor support, in later slides)

11 States A list can therefore be in one of two states:
empty (corresponding to the base case) non-empty (corresponding to the recursive case) The state-based implementation we will study makes this distinction explicit in the representation

12 Empty vs. NonEmpty state (look Ma, no NullPointerException!)
An LRS object delegates all calls to its LRS State object – which can respond to all messages. Empty and NonEmpty states respond differently. There is never a null pointer in the structure.

13 What is basic functionality?
insert new item at front remove item from front set/get first item set/get rest (tail) plus (in Java) methods inherited from Object (toString, equals, etc)

14 How about extensibility?
Enter the Visitor pattern A visitor is an object which encapsulates an algorithm A visitor for the LRS defines what to do in each of the states: emptyCase nonEmptyCase

15 Visitor interface to LRS
the execute method: public Object execute(IAlgo visitor, Object input) first parameter is the visitor second parameter is optional input to the algorithm an Object return value

16 execute definition in states
Empty state: public Object execute(LRS host, IAlgo visitor, Object input){ return visitor.emptyCase(host, input); } NonEmpty state: return visitor.nonEmptyCase(host, input);

17 An empty LRS LRS a = new LRS(); LRS Empty a _state

18 Inserting an item into an empty LRS
a.insertFront(“fred”); LRS Empty a _state

19 Inserting an item into an empty LRS
a.insertFront(“fred”); LRS Empty a _state

20 Inserting an item into an empty LRS
a.insertFront(“fred”); LRS Empty a _state _dat=“fred” _tail NonEmpty

21 Inserting an item into an empty LRS
a.insertFront(“fred”); LRS Empty a _state _dat=“fred” _tail _state NonEmpty LRS

22 Inserting an item into an empty LRS
a.insertFront(“fred”); LRS Empty a _state _dat=“fred” _tail _state NonEmpty LRS

23 Removing an item from an LRS
a.removeFront(); LRS Empty a _state _dat=“fred” _tail _state NonEmpty LRS

24 Removing an item from an LRS
a.removeFront(); LRS Empty These gray objects will be garbage-collected at some point in the future a _state _dat=“fred” _tail _state NonEmpty LRS

25 Designing a visitor (IAlgo)
A visitor to solve a given problem must provide the answer in each of two cases: the empty case the non-empty case We’ve already seen one example: counting the length of a list

26 Length visitor in the empty case the answer is zero
in the non-empty case the answer is one more than the length of the rest of the list public Object emptyCase(LRS host, Object _){ return new Integer(0); } public Object nonEmptyCase(LRS host, Object _){ Integer lengthOfRest=(Integer)(host.getRest().execute(this,_)); return new Integer( 1 + lengthOfRest.intValue() );

27 Aside In pre-Java5 things look a little messy because of the explicit wrapping and unwrapping of the primitive int value (new Integer(…) to wrap, .intValue() to unwrap) and the explicit cast (to Integer).

28 Another visitor How about a visitor for a list of Strings, which doubles each String Ex: starting list: (Fred Wilma Pebbles) resulting list: (FredFred WilmaWilma PebblesPebbles)

29 StringDouble visitor in the empty case there is nothing to do
in the non-empty case the thing to do is to get the first, concatenate it to itself, and set the first to this new value public Object emptyCase(LRS host, Object _){ return null; } public Object nonEmptyCase(LRS host, Object _){ String s = host.getFirst(); host.setFirst(s+s); return host.getRest().execute(this,_);


Download ppt "Lists We’ve seen an array-based list implementation, the ArrayList."

Similar presentations


Ads by Google