Comp Sci 201 Linked Lists Owen Astrachan Jeff

  • Slides: 36
Download presentation
Comp. Sci 201, Linked Lists Owen Astrachan Jeff Forbes October 19, 2017 10/19/17 Compsci

Comp. Sci 201, Linked Lists Owen Astrachan Jeff Forbes October 19, 2017 10/19/17 Compsci 201, Fall 2017, Linked 1

N is for … • new • Allocating memory from the heap • next

N is for … • new • Allocating memory from the heap • next • Moving through elements in a list • Network • The power of Metcalfe’s Law 10/18/17 Compsci 201, Fall 2017, Linked 2

Plan for the Week • APIs and Efficiency • Linear structures • Linked lists

Plan for the Week • APIs and Efficiency • Linear structures • Linked lists explained, uncovered, explored • How does java. util. Linked. List work from both implementation and performance perspective • How are linked lists used to implement other data structures • What are tradeoffs in using linked lists • Code: https: //coursework. cs. duke. edu/201 fall 17/classworklinked/ 10/19/17 Comp. Sci 201, Fall 2017, Linked 3

Stack • Last In First Out (LIFO) 1 2 3 4 5 6 7

Stack • Last In First Out (LIFO) 1 2 3 4 5 6 7 Stack<String> q = new Stack<String>(); q. push("comp "); out. print(q. pop()); q. push("sci "); q. push("is "); q. push("great!"); while(!q. is. Empty()) System. out. print(q. pop());

Stack • Last In First Out (LIFO) 1 2 3 4 5 6 7

Stack • Last In First Out (LIFO) 1 2 3 4 5 6 7 Stack<String> st = new Stack<String>(); st. push("comp "); st. push("sci "); st. push("is "); st. push("great!"); while(!st. is. Empty()) System. out. print(st. pop()); great!is sci comp sci is great!

Queue

Queue

Queue • First In First Out (FIFO) 1 2 3 4 5 6 7

Queue • First In First Out (FIFO) 1 2 3 4 5 6 7 Queue<String> q = new Linked. List<String>(); q. add("comp "); q. add("sci "); q. add("is "); q. add("great!"); while(!q. is. Empty()) System. out. print(q. remove()); comp sci is great!

Stacks & Queues • Reasoning about stacks & queues • WOTO: http: //bit. ly/201

Stacks & Queues • Reasoning about stacks & queues • WOTO: http: //bit. ly/201 -f 17 -1018 -1 • Useful abstraction • How to implement? 10/19/17 Comp. Sci 201, Fall 2017, Linked 8

Empirical and Analytical Analysis • We can run programs to look at "efficiency" •

Empirical and Analytical Analysis • We can run programs to look at "efficiency" • Depends on machine, environment, programs • We can analyze mathematically to look at efficiency from a different point of view • Depends on being able to employ mathematics • What works in theory may not … • We will work on doing both, leading to a better understanding in many dimensions

What is a java. util. List in Java? • Collection of elements, operations? •

What is a java. util. List in Java? • Collection of elements, operations? • Add, remove, traverse, … • What can a list do to itself? • What can we do to a list? • Why more than one kind of list: Array and Linked? • Useful in different applications • How do we analyze differences? • How do we use them in code?

What's the Difference Here? • How does find-a-track work? Fast forward?

What's the Difference Here? • How does find-a-track work? Fast forward?

Analyze Data Structures public double remove. First(List<String> list) { double start = System. nano.

Analyze Data Structures public double remove. First(List<String> list) { double start = System. nano. Time(); while (list. size() != 1){ list. remove(0); } double end = System. nano. Time (); return (end-start)/1 e 9; } List<String> double ltime double atime linked = new Linked. List<String>(); array = new Array. List<String>(); = splicer. remove. First(splicer. create(linked, 100000)); = splicer. remove. First(splicer. create(array, 100000)); • Time taken to remove the first element? https: //coursework. cs. duke. edu/ola/201 -linked-spring 17/blob/master/src/List. Splicer. java

Remove First • Why are timings good? • Why are timings bad? Size 103

Remove First • Why are timings good? • Why are timings bad? Size 103 link array 10 0. 0036 0. 0102 20 0. 0016 0. 0375 30 0. 0012 0. 0756 40 0. 0003 0. 2228 50 0. 0003 0. 235 60 0. 0004 0. 2945 70 0. 0005 0. 3975 80 0. 0007 0. 5456 90 0. 0006 0. 7091 100 0. 0007 0. 8827

Remove Middle Index public double remove. Middle. Index(List<String> list) { double start = System.

Remove Middle Index public double remove. Middle. Index(List<String> list) { double start = System. nano. Time(); while (list. size() != 1){ list. remove(list. size()/2); } double end = System. nano. Time(); return (end-start)/1 e 9; } • What operations could be expensive here? • Explicit: size, remove (only one is expensive) • Implicit: find nth element (may be very costly)

Remove Middle size link array 10 0. 0635 0. 0057 20 0. 2644 0.

Remove Middle size link array 10 0. 0635 0. 0057 20 0. 2644 0. 0131 30 0. 4808 0. 0345 40 0. 8524 0. 0531 50 1. 4025 0. 0844 60 1. 8418 0. 1245 70 2. 9064 0. 1777 80 3. 7237 0. 2224 90 4. 6833 0. 3102 100 7. 8717 0. 3824

Array. List and Linked. List as ADTs • As an ADT (abstract data type)

Array. List and Linked. List as ADTs • As an ADT (abstract data type) Array. List supports • Constant-time or O(1) access to the k-th element • Amortized linear or O(n) storage/time with add • Total storage used in n-element vector is approx. 2 n, spread over all accesses/additions (why? ) • Add/remove in middle is "expensive" O(n), why? • What's underneath here? How Implemented? • Concrete: array – contiguous memory, must be contiguous to support random access • Element 20 = beginning + 20 x size of a pointer

Array. List and Linked. List as ADTs • Linked. List as ADT • Constant-time

Array. List and Linked. List as ADTs • Linked. List as ADT • Constant-time or O(1) insertion/deletion anywhere, but… • Linear or O(n) time to find where, sequential search • Linked good for add/remove at front • Splicing into middle, also for 'sparse' structures • What's underneath? How Implemented • Low-level linked lists, self-referential structures • More memory intensive than array: two pointers

Remove Middle in Pictures for(int k=middle; … a[k] = alist[k+1] Array. List<> alist •

Remove Middle in Pictures for(int k=middle; … a[k] = alist[k+1] Array. List<> alist • Find middle element: happens instantly or O(1) • alist(location) + n/2 * sizeof(pointer) since Array. List holds pointers • Shifting requires moving n/2 pointers, but they are all contiguous in memory: cache performance

Remove Middle in Pictures Linked<> llist • Find middle element: have to follow pointers

Remove Middle in Pictures Linked<> llist • Find middle element: have to follow pointers between elements • Follow n/2 pointers, but all over memory, so takes time to move from memory->cache->use • Removing middle: instantaneous, no shifting, just reassign a couple of pointers (back pointers too) • Blue points to Yellow

Analytical Analysis • Since Linked. List is roughly linear • Time to remove first

Analytical Analysis • Since Linked. List is roughly linear • Time to remove first element is constant, but must be done N times • Time for one removal is O(1) --- constant and doesn't depend on N • Time for all removals is O(N) – linear in N, but slope doesn't matter • For Array. List, removing first element entails … • Shifting N-1 elements, so this is O(N) • All: (N-1) + (N-2) + … + 3 + 2 + 1 = O(? )

Barbara Liskov Turing Award Winner in 2008 for For contributions to practical and theoretical

Barbara Liskov Turing Award Winner in 2008 for For contributions to practical and theoretical foundations of programming language and system design, especially related to data abstraction, fault tolerance, and distributed computing. The advice I give people in general is that you should figure out what you like to do, and what you can do well—and the two are not all that dissimilar, because you don’t typically like doing something if you don’t do it well. … So you should instead watch—be aware of what you’re doing, and what the opportunities are, and step into what seems right, and see where it takes you.

Concrete Implementation: Linked List

Concrete Implementation: Linked List

Pointers, References, Structures • Study Linked. List and linked lists from basics • Useful

Pointers, References, Structures • Study Linked. List and linked lists from basics • Useful in understanding Java implementations • Useful to understand C, C++ • Useful in understanding trees • Required in other courses, interviews, etc. • Low-level abstraction, high-order abstraction • How can you implement structures that allow arbitrary splicing in the middle?

Goldilocks and the Hashtable • A hashtable is a collection of buckets • Find

Goldilocks and the Hashtable • A hashtable is a collection of buckets • Find the right bucket and search it • Bucket organization? • Array, linked list, search tree

Structuring Data: The inside story • How does a Hash. Set work? Simple. Hash.

Structuring Data: The inside story • How does a Hash. Set work? Simple. Hash. String. Set, almost the same as Hash. Map • What happens with add(key) in a Hash. Set? • What happens with contains(key)? • What happens with remove(key)? • In diagram below, what's in each cell of my. Table? • Array. List: advantages? Disadvantages?

Set Implementations Set. Driver. java Size Unique Array Util. hash Hash. Array Hash. Link

Set Implementations Set. Driver. java Size Unique Array Util. hash Hash. Array Hash. Link Melville 14353 4103 0. 43 0. 15 0. 216 0. 104 hawthorne 85753 13542 1. 84 0. 21 0. 288 0. 188 kjv 10 82313 5 32674 14. 77 0. 71 0. 558 0. 584 l l Array: search entire array for each add Class java. util. Hash. Set Hash. Array: buckets are Array. List objects Hash. Link: buckets are low-level linked lists https: //coursework. cs. duke. edu/201 fall 17/classwork-linked/

Set Implementations, Set. Stress. java Array Util. hash Hash. Array Hash. Link 10, 000

Set Implementations, Set. Stress. java Array Util. hash Hash. Array Hash. Link 10, 000 0. 857 0. 037 0. 023 0. 020 20, 000 3. 384 0. 015 0. 014 0. 010 30, 000 6. 884 0. 024 0. 016 0. 024 40, 000 14. 833 0. 012 0. 030 0. 019 l Can we run without edit/recompile/run cycle? Ø Benefits? Drawbacks? Ø Why Java interfaces are a good idea for allowing different concrete implementations https: //coursework. cs. duke. edu/201 fall 17/classwork-linked/

Linked lists, CDT and ADT • As an ADT • A list is empty,

Linked lists, CDT and ADT • As an ADT • A list is empty, or contains an element and a list • ( ) or (x, (y, ( ) ) ) • As a picture p • CDT (concrete data type) pojo: plain old Java object public class Node{ String info; Node next; } Node p = new Node(); p. info = "hello"; p. next = null;

Building linked lists • Add words to the front of a list (draw a

Building linked lists • Add words to the front of a list (draw a picture) • Create new node pointing to list, reset start of list public class Node { String info; Node next; public Node(String s, Node link){ value = s; next = link; } } // … declarations here List. Node list = null; while (scanner. has. Next()) { list = new List. Node(scanner. next(), list); } • What about adding to the end of the list? • http: //www. pythontutor. com/java. html

Adding to End (iterative) void add. At. End(Node head, String value) { if (head

Adding to End (iterative) void add. At. End(Node head, String value) { if (head == null) head = new Node(value, null); else { Node current = head; while (current. next != null) current = current. next; // what’s true here? current. next = new Node(value, null); } } • What is true after the while loop? • How can we do this recursively?

Adding to End (recursive) public Node add. At. End(Node head, String value) { if

Adding to End (recursive) public Node add. At. End(Node head, String value) { if (head == null) return new Node(value, null); head. next = add. At. End(head. next, value); return head; } • What is the base case?

Dissection of add-to-front • List initially empty • First node has first word list

Dissection of add-to-front • List initially empty • First node has first word list A list = new Node(word, list); Node(String s, Node link) { info = s; next = link; } B • Each new word causes new node to be created • New node added to front l rhs of operator = completely evaluated before assignment

Standard list processing (iterative) • Visit all nodes once, e. g. , count them

Standard list processing (iterative) • Visit all nodes once, e. g. , count them or process them public int size(Node list){ int count = 0; while (list != null) { count += 1; list = list. next; } return count; } • Should we be concerned that list is null on return? • Can we change the data in the list nodes? • Append “s” to all strings in list?

Removing Node from list, "cat" list "dog" "cat" "pig" public Node remove(Node list, String

Removing Node from list, "cat" list "dog" "cat" "pig" public Node remove(Node list, String s){ Node start = list; // special case 'cat' first, not shown while (list. next != null) { if (list. next. info. equals(s)) { list. next = list. next; break; } list = list. next; } return start; }

Linked List idioms • Sometimes check list == null and list. next == null

Linked List idioms • Sometimes check list == null and list. next == null • Short-circuit evaluation in how to do this? • First node can be tricky to process, e. g. , remove • Has no node before it. • Solution: put a "header" or "empty" node first • Typically loop: while(list != null) • Can be useful to do while (list. next != null) • Must be sure list != null in writing this!!!

Link Questions http: //bit. ly/201 -f 17 -1018 -2 Why is the parameter in

Link Questions http: //bit. ly/201 -f 17 -1018 -2 Why is the parameter in remove method Object and not String?