15 utan frÅgor · 2014. 3. 4. · 20140304 1 d0010e! lecture 15! headers! multiple iterators!...
TRANSCRIPT
2014-‐03-‐04
1
D0010E!Lecture 15!
Headers!
Multiple Iterators!
Implementing Singly Linked!
Lists!
Pre-Pointers!
Iterator Integrity!
Implementatons based on arrays!
Lecture 15 -‐ Håkan Jonsson 1
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 2
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 3
2014-‐03-‐04
2
1. Why should list classes hide their nodes?
• Last lecture we saw examples of linked lists and their implementaBons.
• We could create a list by, for example, SimpleSingleList<Integer> s = " "SimpleSingleList<Integer>(); "
• Now, each list had a private node class that was encapsulated.
• Each list maintained a chain of nodes.
Lecture 15 -‐ Håkan Jonsson 4
DeckOfCards
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 5
2. ImplementaBon strategies • The implementaBon of a singly linked listed we saw last lecture can be improved in two ways.
• One way is to always have a “dummy” node at the beginning of the internal node list. – This node is called a header and never used to store data.
• It makes operaBons on the list simpler.
Lecture 15 -‐ Håkan Jonsson 6
The header keeps track of the first node The header node
2014-‐03-‐04
3
ImplementaBon strategies • Once we have a header, another improvement is possible: – Internally, to keep track of an inner node n, we use a reference variable that points to the node immediately before n.
• The variable is called a pre-‐pointer. – Only possible because we have a header.
• Makes it easier to manipulate nodes via the pointer.
Lecture 15 -‐ Håkan Jonsson 7
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 8
3. Example: SingleList<E> • An implementaBon of a singly linked list with a header and a
pre-‐pointer. • It also has a "finger" that points at an element and can be
moved.
Lecture 15 -‐ Håkan Jonsson 9
The list contains 4 elements and the finger points at the second. Internally, it has 5 nodes and a pre-‐pointer that always points immediately before where the finger is.
2014-‐03-‐04
4
Lecture 15 -‐ Håkan Jonsson 10
+ atLast() : boolean+ isEmpty() : boolean+ item() : E+ toStart() : void+ goForth() : void+ insertFirst(item : E) : void+ insertAfter(item : E) : void+ removeFirst() : void+ removeAfter() : void+ iterator() : Iterator<E>
SimpleList<E>
– print(msg : String, end : String) : void+ printFirst(method : String) : void+ printLast() : void
SimpleListMIddleClass<E>
+ main(args : String[] ) : voidSimpleListMain<E>
+ insertFirst(item : E) : void+ insertAfter(item : E) : void+ removeFirst() : void+ removeAfter() : void
SimpleListDebug<E>
SimpleListIterator<E>
+ hasNext() : boolean+ next() : void+ remove() : void
<<interface>>Iterator<E>
+ iterator() : Iterator<E>
<<interface>>Iterable<E>
+ setChanged() : void+ notifyObservers() : void+ addObservers(obj : Observer) : void
Observable
+ <<abstract>> atLast() : boolean+ <<abstract>> isEmpty() : boolean+ <<abstract>> item() : E+ <<abstract>> toStart() : void+ <<abstract>> goForth() : void+ <<abstract>> insertFirst(item : E) : void+ <<abstract>> insertAfter(item : E) : void+ <<abstract>> removeFirst() : void+ <<abstract>> removeAfter() : void+ <<abstract>> iterator() : Iterator<E>
<<abstract>>SimpleListADT<E>
+ update() : void
<<interface>>Observer
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 11
4. MulBple iterators • The class SingleList has one (1) iterator that was
illustrated with a poinFng finger. – This finger can be moved forward through the list and back to the first element again via methods in the class.
– The implementaBon of this finger was based on a pre-‐pointer.
• A limitaBon was that all client objects had to share this single finger.
• To overcome this, we use the Iterator design paGern and add the ability to create an arbitrary number of iterator objects, separate from the actual list, to iterate over the list. – These iterators can only be used to read, not alter, the elements of the list.
Lecture 15 -‐ Håkan Jonsson 12
2014-‐03-‐04
5
Lecture 15 -‐ Håkan Jonsson 13
+ atLast() : boolean+ isEmpty() : boolean+ item() : E+ toStart() : void+ goForth() : void+ insertFirst(item : E) : void+ insertAfter(item : E) : void+ removeFirst() : void+ removeAfter() : void+ iterator() : Iterator<E>
SimpleList<E>
– print(msg : String, end : String) : void+ printFirst(method : String) : void+ printLast() : void
SimpleListMIddleClass<E>
+ main(args : String[] ) : voidSimpleListMain<E>
+ insertFirst(item : E) : void+ insertAfter(item : E) : void+ removeFirst() : void+ removeAfter() : void
SimpleListDebug<E>
SimpleListIterator<E>
+ hasNext() : boolean+ next() : void+ remove() : void
<<interface>>Iterator<E>
+ iterator() : Iterator<E>
<<interface>>Iterable<E>
+ setChanged() : void+ notifyObservers() : void+ addObservers(obj : Observer) : void
Observable
+ <<abstract>> atLast() : boolean+ <<abstract>> isEmpty() : boolean+ <<abstract>> item() : E+ <<abstract>> toStart() : void+ <<abstract>> goForth() : void+ <<abstract>> insertFirst(item : E) : void+ <<abstract>> insertAfter(item : E) : void+ <<abstract>> removeFirst() : void+ <<abstract>> removeAfter() : void+ <<abstract>> iterator() : Iterator<E>
<<abstract>>SimpleListADT<E>
+ update() : void
<<interface>>Observer
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 14
5. Iterator integrity • When we create an iterator, it should go through those
elements that are contained in the list at that moment and no other.
• Since the list is mutable, it could very well be changed before iterators have gone through all the elements in their version of the list.
• It is a challenge to handle such a situaBon, keeping different versions of lists available to the iterators.
• The simplest soluBon is to instead invalidate all iterators as soon as the list changes. – Note: If this is not suitable behavior, there exists alternaBves
(persistent data structures, for example). – If needed, a "snap shot" of the list can be made by simply
making a copy. • We add automaBc invalidaBon of iterators by using the
Observer design paGern.
Lecture 15 -‐ Håkan Jonsson 15
2014-‐03-‐04
6
Lecture 15 -‐ Håkan Jonsson 16
+ atLast() : boolean+ isEmpty() : boolean+ item() : E+ toStart() : void+ goForth() : void+ insertFirst(item : E) : void+ insertAfter(item : E) : void+ removeFirst() : void+ removeAfter() : void+ iterator() : Iterator<E>
SimpleList<E>
– print(msg : String, end : String) : void+ printFirst(method : String) : void+ printLast() : void
SimpleListMIddleClass<E>
+ main(args : String[] ) : voidSimpleListMain<E>
+ insertFirst(item : E) : void+ insertAfter(item : E) : void+ removeFirst() : void+ removeAfter() : void
SimpleListDebug<E>
SimpleListIterator<E>
+ hasNext() : boolean+ next() : void+ remove() : void
<<interface>>Iterator<E>
+ iterator() : Iterator<E>
<<interface>>Iterable<E>
+ setChanged() : void+ notifyObservers() : void+ addObservers(obj : Observer) : void
Observable
+ <<abstract>> atLast() : boolean+ <<abstract>> isEmpty() : boolean+ <<abstract>> item() : E+ <<abstract>> toStart() : void+ <<abstract>> goForth() : void+ <<abstract>> insertFirst(item : E) : void+ <<abstract>> insertAfter(item : E) : void+ <<abstract>> removeFirst() : void+ <<abstract>> removeAfter() : void+ <<abstract>> iterator() : Iterator<E>
<<abstract>>SimpleListADT<E>
+ update() : void
<<interface>>Observer
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 17
6. ImplemenBng singly linked lists with arrays • Computer memory is organized as a (huge) array. – This array holds both code and data when a program is executed.
– Any variable (data structure) in a program is stored in this array.
• TradiBonally, programs manipulate this array directly.
• Let's look at how lists can be implemented directly in the array.
Lecture 15 -‐ Håkan Jonsson 18
2014-‐03-‐04
7
Internal list nodes
Lecture 15 -‐ Håkan Jonsson 19
ImplemenBng lists with arrays
Lecture 15 -‐ Håkan Jonsson 20
Make sure you understand how indices are subsBtutes for references!
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 21
2014-‐03-‐04
8
Lecture 15 -‐ Håkan Jonsson 22
7. Raw lists • What if there are no objects, no references, and no keyword new?!
• We could then simulate references by using array indices. – Like before.
• And then let what was a node object be a piece of the array. – Assume we only store integers or some other primiBve type of data in the array.
• Note: – This hints to the origin of the word "primiBve" in "primiBve types"; they are very basic types that fit in a memory cell.
Raw lists
Lecture 15 -‐ Håkan Jonsson 23
• Each node contains data (its content) and the index in the array (the link) of the next node. – Here, 2 array elements per
node. – So, every node starts at an
index that is even. • The array to the leb has size
32 and has space for 16 list nodes.
• The blue part represents the list A B C D E F
• Red marks unused space.
A E B C
F D
(-‐1)
0 1 2 3 4 5 6 7 8 9
10 11 12 13 ..
Array index
.. 29 30 31
The list
12
E
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 24
2014-‐03-‐04
9
8. Memory management
Lecture 15 -‐ Håkan Jonsson 25
A E B C
F D
(-‐1)
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
The list
• How do we find a free (unused) node when we do insert?
• Easy soluBon: – Assign all links -‐1 in the
beginning. • At insert, scan through the
array unBl a node with -‐1 as its link is found.
• When a node is deleted, re-‐wire the link of the previous node to pass by the node, and assign its link -‐1 again.
Memory management
Lecture 15 -‐ Håkan Jonsson 26
A E B C
F D
(-‐1)
Free space
(-‐1)
The list
• Befer soluBon: – Put the unused nodes into
another list. – A free space list. – So, the array contains 2 lists at
the same Bme. • At first, all nodes belong to the
free space list. • Then nodes are moved
between the two as needed. – Unused nodes are stored in the
free space list unBl needed. • No need any longer to scan.
– Much more efficient. – However, costs one more
variable to hold the start of the free space list.
Memory management • Since we have two lists in our
array, we can break them apart so they are no longer lined up.
• This gives us a good view of what is known as pointer chains.
– The links are the pointers. • If we let the Java virtual machine
(that runs our programs) keep track of the free space list, it can then set aside new space for nodes (objects) when we use new.
• So, all our dynamic objects are linked together by pointer chains like this.
– More complicated in reality since, for instance, nodes can have different sizes.
Lecture 15 -‐ Håkan Jonsson 27
A
E
B
C
F D
Free space
The list
2014-‐03-‐04
10
Lecture 15
• 1. Why should list classes hide their nodes? • 2. ImplementaBon strategies • 3. Example: SingleList<E> • 4. MulBple iterators • 5. Iterator integrity • 6. ImplemenBng singly linked lists with arrays • 7. Raw lists • 8. Memory management
Lecture 15 -‐ Håkan Jonsson 28