Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 23: Doubly Linked List

Similar presentations


Presentation on theme: "Lecture 23: Doubly Linked List"— Presentation transcript:

1 Lecture 23: Doubly Linked List
CSE 116/504 – Intro. To Computer Science for Majors II Lecture 23: Doubly Linked List

2 "Convince your neighbors"
Announcements Lectures have typical pattern for adult learning Ask question (ungraded) "Convince your neighbors" Ask question (graded) May see input dialog in TopHat but no question on screen Ignore these questions; testing students paying attention Lose points for answering; me having some "fun" Public domain picture of the creepy clown. Original available at:

3 What Can We Know About List?
List interface defined in java.util package Specifies all of the methods we can call on a List Effect of each method included in these definition Also includes value returned & potential exceptions Start TopHat slide –do NOT show to class

4 List ADT Based upon a imagined resizable array
Arbitrary sequence of elements stored within list List ADT keeps elements indexed from 0 to n-1 Index just int; gives absolute position in List 1 2 3 4 5

5 Linked List Nodes ("thingys") very limited in functionality
Design splits Entry from List implementation Excellent OO design: each class focused on 1 job LinkedList head size  4 modCount  99 Advance TopHat slide – still do NOT show to class Entry Entry Entry Entry elem next elem next elem next elem next

6 1st Key Point for Linked Lists
Linked list chain of Entrys Entry is linked list

7 2nd Key Point for Linked Lists
Entry holds element Entry is element

8 List Methods boolean add(E e); void add(int i, E e);
E set(int i, E e); boolean remove(Object o); E remove(int i); boolean contains(Object o); int indexOf(Object o); E get(int i); // size(),isEmpty(),iterator() & other boring ones

9 Linked lists use Entrys but
List Method Issue Linked lists use Entrys but List interface specifies int boolean add(E e); void add(int i, E e); E set(int i, E e); boolean remove(Object o); E remove(int i); boolean contains(Object o); int indexOf(Object o); E get(int i); // size(),isEmpty(),iterator() & other boring ones

10 3rd Key Point for Linked Lists
LinkedList is-a List Traverses Entrys to reach target

11 Fill in the Blank trav.getNext(); trav += 1; trav.getElement();
Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext(); 1

12 Convince neighbor your answer
Fill in the Blank Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while Convince neighbor your answer is correct trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext();

13 Fill in the Blank trav.getNext(); trav += 1; trav.getElement();
Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext(); 1

14 Entry IS NOT index Fill in the Blank trav.getNext(); trav += 1;
Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while Entry IS NOT index trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext();

15 Entry IS NOT element Fill in the Blank trav.getNext(); trav += 1;
Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext(); Entry IS NOT element

16 Closer, but what happens to return value?
Fill in the Blank Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while Closer, but what happens to return value? trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext();

17 trav never assigned to new alias!
Fill in the Blank Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while Closer, but what happens to return value? trav never assigned to new alias! trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext();

18 trav never assigned to new alias!
Fill in the Blank Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while trav never assigned to new alias! Return value goes: trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext();

19 Fill in the Blank trav.getNext(); trav += 1; trav.getElement();
Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext(); Gets next Entry in list

20 AND reassigns trav so it aliases next Node
Fill in the Blank Entry<E> trav = head while (trav != null && !/* found node */) /* Update vars helping find node */ ___________________ end while trav.getNext(); trav += 1; trav.getElement(); trav = trav.getNext(); Gets next Entry in list AND reassigns trav so it aliases next Node

21 Traversal Algorithm Starts List method needing non-head nodes
Entry<E> trav = head while (trav != null && ! /* found node */ ) /* Update vars helping find node */ trav = trav.getNext() end while /* Now use trav to complete method */

22 Traversal's Big-Oh Complexity?
Entry<E> trav = head while (trav != null && !/*found node*/) /* Update vars helping find node */ trav = trav.getNext() end while Impossible to know without the number of nodes in linked list O(n) Depends on where the needed node is O(1) 1

23 Traversal's Big-Oh Complexity?
Entry<E> trav = head while (trav != null && !/*found node*/) /* Update vars helping find node */ trav = trav.getNext() end while Convince neighbor your answer is correct Impossible to know without the number of nodes in linked list O(n) Depends on where the needed node is O(1)

24 Traversal's Big-Oh Complexity?
Entry<E> trav = head while (trav != null && !/*found node*/) /* Update vars helping find node */ trav = trav.getNext() end while Impossible to know without the number of nodes in linked list O(n) Depends on where the needed node is O(1) 1

25 Traversal's Big-Oh Complexity?
Entry<E> trav = head while (trav != null && !/*found node*/) /* Update vars helping find node */ trav = trav.getNext() end while Big-Oh based on input size; linked list is input, so number of nodes = n Impossible to know without the number of nodes in linked list O(n) Depends on where the needed node is O(1)

26 Traversal's Big-Oh Complexity?
Entry<E> trav = head while (trav != null && !/*found node*/) /* Update vars helping find node */ trav = trav.getNext() end while Impossible to know without the number of nodes in linked list O(n) Depends on where the needed node is O(1) Big-Oh measures worst case; assume node not found

27 Traversal's Big-Oh Complexity?
Entry<E> trav = head while (trav != null && !/*found node*/) /* Update vars helping find node */ trav = trav.getNext() end while Impossible to know without the number of nodes in linked list O(n) Depends on where the needed node is O(1) Does constant work

28 Traversal's Big-Oh Complexity?
Entry<E> trav = head while (trav != null && !/*found node*/) /* Update vars helping find node */ trav = trav.getNext() end while Impossible to know without the number of nodes in linked list O(n) Depends on where the needed node is O(1) Does constant work for every node

29 Traversal's Big-Oh Complexity?
Entry<E> trav = head while (trav != null && !/*found node*/) /* Update vars helping find node */ trav = trav.getNext() end while Impossible to know without the number of nodes in linked list O(n) Depends on where the needed node is O(1) Does constant work for every node in worst case

30 ArrayList v. LinkedList
Method ArrayList LinkedList w/ tail remove(i) O(n) (generally) O(1) (if i=0) remove(e) O(n) contains(e) indexOf(e) get(i)/ set(i,e) O(1) (at either end) add(e) O(1) add(i,e)

31 Array-based List.remove(i)
remove(i) "shifts" elements down to fill hole O(n) time required in the general case If i =size()-1, have special best case of O(1) time But must consider worst case when computing big-Oh 1 2 e n-1 i

32 Array-based List.add(i, e)
add(i, e) "shifts" elements to make space in array When array fills, must allocate new array & copy over Time needed based on i – amount getting moved If adding to end, have best case of O(1) time O(n) general/worst case from shifting all elements 1 2 n-1 i

33 Array-based List.add(i, e)
add(i, e) "shifts" elements to make space in array When array fills, must allocate new array & copy over Time needed based on i – amount getting moved If adding to end, have best case of O(n) time O(n) general/worst case from shifting all elements 1 2 n-1 i

34 Other List’s Methods remove() removes element IF in List already
Requires comparing with elements currently in List contains() checks if element already included indexOf() returns first index or -1 if not in list get()/set() uses element at specific index No comparison required, just requires using array index

35 ArrayList v. LinkedList
Method ArrayList LinkedList w/ tail remove(i) O(n) (generally) O(1) (if i=size-1) O(1) (if i=0) remove(e) O(n) contains(e) indexOf(e) get(i)/ set(i,e) O(1) O(1) (at either end) add(e) add(i,e)

36 ArrayList v. LinkedList
Method ArrayList LinkedList w/ tail remove(i) O(n) (generally) O(1) (if i=size-1) O(1) (if i=0) remove(e) O(n) contains(e) indexOf(e) get(i)/ set(i,e) O(1) O(1) (at either end) add(e) add(i,e) O(1) (at either end)

37 Problem with Singly Linked
tail improves performance at List's end add(e) like add(0,e) but uses tail rather head When head or tail used, get() & set() very quick remove() with tail slow; traverse to find prior node LinkedList head tail size  4 Entry Entry Entry Entry elem next elem next elem next elem next

38 Using Singly Linked List
Nodes added & removed along with elements Unlike array-based List, limits demands on memory 1st and last element quick to add, retrieve, & update O(1) time makes linked list fastest removing 1st element Slowest removing last element needing full O(n) time

39 Using Singly Linked List
Nodes added & removed along with elements Unlike array-based List, limits demands on memory 1st and last element quick to add, retrieve, & update O(1) time makes linked list fastest removing 1st element Slowest removing last element needing full O(n) time Means linked lists great when end elements used But not equally, add either end but only remove head

40 Using Singly Linked List
Nodes added & removed along with elements Unlike array-based List, limits demands on memory 1st and last element quick to add, retrieve, & update O(1) time makes linked list fastest removing 1st element Slowest removing last element needing full O(n) time Means linked lists great when end elements used But not equally, add either end but only remove head

41 Doubly Linked List Link to previous node in list also in each node
Each doubly-linked node contains: Element (data) reference Link to next Entry Prev(ious) Entry also linked elem Doubly-linked node next prev

42 Doubly Linked List Link to previous node in list also in each node
Each doubly-linked node contains: Element (data) reference Link to next Entry Prev(ious) Entry also linked

43 Implementing Entry Doubly-linked node could extend Entry
next & elem fields exist in both of these classes Only difference is prev field added for doubly-linked Allows mixing singly- & doubly-linked in same list But this is weird and would almost never happen Prevent this monstrosity! Do not use inheritance here

44 1st Entry Class (Singly-Linked)
public class Entry<T> { private T element; private Entry<T> next; public Entry(T e, Entry<T> n) { element = e; next = n; } public T getElement() { return element; } public Entry<T> getNext() { return next; } // Rest of the getters and setters omitted because they are boring }

45 2nd Entry Class (Doubly-Linked)
public class Entry<Bob> { private Bob element; private Entry<Bob> next, prev; public Entry(Bob e, Entry<Bob> n, Entry<Bob> p) { element = e; next = n; prev = p; } public Bob getElement() { return element; } public Entry<Bob> getNext() { return next; } public void setPrev(Entry<Bob> newPrev) { prev = newPrev; } // Rest of the getters and setters omitted because they are boring }

46 2nd Entry Class (Doubly-Linked)
public class Entry<Bob> { private Bob element; private Entry<Bob> next, prev; public Entry(Bob e, Entry<Bob> n, Entry<Bob> p) { element = e; next = n; prev = p; } public Bob getElement() { return element; } public Entry<Bob> getNext() { return next; } public void setPrev(Entry<Bob> newPrev) { prev = newPrev; } // Rest of the getters and setters omitted because they are boring }

47 2nd Entry Class (Doubly-Linked)
public class Entry<T> { private T element; private Entry<T> next, prev; public Entry(T e, Entry<T> n, Entry<T> p) { element = e; next = n; prev = p; } public T getElement() { return element; } public Entry<T> getNext() { return next; } public void setPrev(Entry<T> newPrev) { prev = newPrev; } // Rest of the getters and setters omitted because they are boring }

48 Removing the Tail Use Entry's prev field to get next-to-last Entry
Avoids the O(n) traversal using O(1) field lookup Just set tail field in LinkedList class like this: tail = tail.getPrev(); LinkedList head tail size  4 modCount  6

49 Removing the Tail Use Entry's prev field to get next-to-last Entry
Avoids the O(n) traversal using O(1) field lookup Just set tail field in LinkedList class like this: tail = tail.getPrev(); LinkedList head tail size  4 modCount  6

50 Removing the Tail Use Entry's prev field to get next-to-last Entry
Avoids the O(n) traversal using O(1) field lookup Just set tail field in LinkedList class like this: tail = tail.getPrev(); size -= 1; modCount += 1; LinkedList head tail size  3 modCount  7

51 Removing the Tail Use Entry's prev field to get next-to-last Entry
Avoids the O(n) traversal using O(1) field lookup Just set tail field in LinkedList class like this: tail = tail.getPrev(); size -= 1; modCount += 1; LinkedList head tail size  3 modCount  7

52 Removing the Tail Use Entry's prev field to get next-to-last Entry
Avoids the O(n) traversal using O(1) field lookup Just set tail field in LinkedList class like this: tail = tail.getPrev(); size -= 1; modCount += 1; LinkedList head tail size  3 modCount  7

53 Removing the Tail Use Entry's prev field to get next-to-last Entry
Avoids the O(n) traversal using O(1) field lookup Just set tail field in LinkedList class like this: tail = tail.getPrev(); size -= 1; modCount += 1; tail.setNext(null); LinkedList head tail size  3 modCount  7

54 Removing the Tail Use Entry's prev field to get next-to-last Entry
Avoids the O(n) traversal using O(1) field lookup Just set tail field in LinkedList class like this: tail = tail.getPrev(); size -= 1; modCount += 1; tail.setNext(null); LinkedList head tail size  3 modCount  7

55 Removing the Tail Use Entry's prev field to get next-to-last Entry
Avoids the O(n) traversal using O(1) field lookup Just set tail field in LinkedList class like this: tail = tail.getPrev(); size -= 1; modCount += 1; tail.setNext(null); LinkedList head tail size  3 modCount  7

56 Removing an Internal Node
Linked list's length equals number of elements Requires unlinking Entry from linked list Nothing fancy needed, just adjust prev & next links Entry 0nly included because of links, so this does it all

57 Removing an Internal Node
Requires unlinking Entry from linked list Nothing fancy needed, just adjust prev & next links Entry 0nly included because of links, so this does it all LinkedList head tail size  3 modCount 3

58 Removing an Internal Node
Requires unlinking Entry from linked list Nothing fancy needed, just adjust prev & next links Entry 0nly included because of links, so this does it all LinkedList head tail size  3 modCount 3

59 Removing an Internal Node
Requires unlinking Entry from linked list Nothing fancy needed, just adjust prev & next links Entry 0nly included because of links, so this does it all LinkedList head tail size  3 modCount 3

60 Removing an Internal Node
Requires unlinking Entry from linked list Nothing fancy needed, just adjust prev & next links Entry 0nly included because of links, so this does it all LinkedList head tail size  2 modCount 4

61 Removing Internal Node
public class LinkedList<T> implements List<T> { private Entry<T> head; private Entry<T> tail; private int size; private long modCount; private void removeInternalNode(Entry<T> removeMe) { Entry<T> prior, follow;

62 Removing Internal Node
public class LinkedList<T> implements List<T> { private Entry<T> head; private Entry<T> tail; private int size; private long modCount; private void removeInternalNode(Entry<T> removeMe) { Entry<T> prior, follow;

63 Removing Internal Node
public class LinkedList<T> implements List<T> { /* More code exists, but removed for space */ private void removeInternalNode(Entry<T> removeMe) { Entry<T> prior, follow; LinkedList head tail size  2 modCount 4 prior

64 Removing Internal Node
public class LinkedList<T> implements List<T> { /* More code exists, but removed for space */ private void removeInternalNode(Entry<T> removeMe) { Entry<T> prior, follow; prior = removeMe.getPrev(); LinkedList head tail size  2 modCount 4 follow prior

65 Removing Internal Node
public class LinkedList<T> implements List<T> { /* More code exists, but removed for space */ private void removeInternalNode(Entry<T> removeMe) { Entry<T> prior, follow; prior = removeMe.getPrev(); follow = removeMe.getNext(); LinkedList head tail size  2 modCount 4 follow prior

66 Removing Internal Node
public class LinkedList<T> implements List<T> { /* More code exists, but removed for space */ private void removeInternalNode(Entry<T> removeMe) { Entry<T> prior, follow; prior = removeMe.getPrev(); follow = removeMe.getNext(); prior.setNext( ); LinkedList head tail size  2 modCount 4 follow prior

67 Removing Internal Node
public class LinkedList<T> implements List<T> { /* More code exists, but removed for space */ private void removeInternalNode(Entry<T> removeMe) { Entry<T> prior, follow; prior = removeMe.getPrev(); follow = removeMe.getNext(); prior.setNext(follow); follow.setPrev( ); LinkedList head tail size  2 modCount 4 follow prior

68 Removing Internal Node
public class LinkedList<T> implements List<T> { /* More code exists, but removed for space */ private void removeInternalNode(Entry<T> removeMe) { Entry<T> prior, follow; prior = removeMe.getPrev(); follow = removeMe.getNext(); prior.setNext(follow); follow.setPrev(prior); size -= 1; modCount += 1; } LinkedList head tail size  2 modCount 4 follow prior

69 Coding is hard Drawing is easy Using drawings makes coding easier
Programming Pro Tip Coding is hard Drawing is easy Using drawings makes coding easier

70 Almost Forgot Easy writing two of LinkedList boring methods
size() -- returns size isEmpty() – returns if size is equal to 0 Easy start to third method since it has little work iterator() -- returns new LLIterator(); But now we must write LLIterator class

71 Almost Forgot Easy writing two of LinkedList boring methods
size() -- returns size isEmpty() – returns if size is equal to 0 Easy start to third method since it has little work iterator() -- returns new LLIterator(); But now we must write LLIterator class

72 But Not That Much Work

73 Type of LLIterator's Cursor?

74 Best LLIterator Cursor Type?
LLIterator lacks array, so no cursor is required T (the element type) Entry (the node type) int 18

75 Best LLIterator Cursor Type?
LLIterator lacks array, so no cursor is required T (the element type) Entry (the node type) int Convince neighbor your answer is correct

76 Best LLIterator Cursor Type?
LLIterator lacks array, so no cursor is required T (the element type) Entry (the node type) int 1

77 Best LLIterator Cursor Type?
LLIterator lacks array, so no cursor is required T (the element type) Entry (the node type) int

78 Best LLIterator Cursor Type?
LLIterator lacks array, so no cursor is required T (the element type) Entry (the node type) int Cursor used to access elements; cannot use element to access elements

79 Best LLIterator Cursor Type?
LLIterator lacks array, so no cursor is required T (the element type) Entry (the node type) int

80 Best LLIterator Cursor Type?
LLIterator lacks array, so no cursor is required T (the element type) Entry (the node type) int Cursor used to access elements; in a linked list, we use nodes to hold & access elements

81 Last Linked List Key Concept
Entry in LLIterator equivalent to index in ArrayListIterator

82 Final LLIterator Details
if cursor will access a valid location value at cursor’s location Advance cursor to refer to next location if (cursor != null) cursor.getElement() cursor.getNext()

83 Final LLIterator Details
if cursor will access a valid location value at cursor’s location Advance cursor to refer to next location if (cursor != null) cursor.getElement() cursor.getNext()* * If you are not objecting, today's 1st TopHat failed

84 Final LLIterator Details
if cursor will access a valid location value at cursor’s location Advance cursor to refer to next location if (cursor != null) cursor.getElement() cursor = cursor.getNext()

85 Does Absolute Position Matter?

86 Nodes Help With Relative Order

87 ArrayList v. LinkedList
Method ArrayList LinkedList w/ tail remove(i,e) O(n) (generally) O(1) (if i=size-1) O(1) (if i=0) remove(e) O(n) contains(e) indexOf(e) get(i)/ set(i,e) O(1) O(1) (at either end) add(e) add(i,e) O(1) (at either end)

88 1st Key Point for Linked Lists
Linked list chain of Entrys Entry is linked list

89 2nd Key Point for Linked Lists
Entry holds element Entry is element

90 Linked lists use Entrys but
List Method Issue Linked lists use Entrys but List interface specifies int boolean add(E e); void add(int i, E e); E set(int i, E e); boolean remove(Object o); E remove(int i); boolean contains(Object o); int indexOf(Object o); E get(int i); // size(),isEmpty(),iterator() & other boring ones

91 Last Linked List Key Concept
Entry in LinkListIterator equivalent to index in ArrayListIterator

92 3rd Key Point for Linked Lists
LinkedList is-a List Traverses Entrys to reach target

93 Traversal Algorithm Starts List method needing non-head nodes
Entry<E> trav = head while (trav != null && ! /* found node */ ) /* Update vars helping find node */ trav = trav.getNext() end while /* Now use trav to complete method */

94 Coding is hard Drawing is easy Using drawings makes coding easier
Programming Pro Tip Coding is hard Drawing is easy Using drawings makes coding easier

95 For Next Lecture Monday reviews material from midterm
What are your questions from this midterm? What was your grade and can you see results? Were the Tim Hertz-tons questions from real world? Week #8 assignment available & due on Monday Can finish assignment now & relax this weekend! Phase #2 due in 10 days – make sure group is ready


Download ppt "Lecture 23: Doubly Linked List"

Similar presentations


Ads by Google