1 / 57

Lecture Objectives

Lecture Objectives. Linked list data structures: Singly-linked (cont.) Doubly-linked Circular Implementing the List interface as a linked list The Iterator interface Implementing Iterator for a linked list. Double-Linked Lists and Circular Lists. Double-Linked Lists.

tablita
Télécharger la présentation

Lecture Objectives

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lecture Objectives • Linked list data structures: • Singly-linked (cont.) • Doubly-linked • Circular • Implementing the List interface as a linked list • The Iterator interface • Implementing Iterator for a linked list CS340

  2. Double-Linked Lists and Circular Lists CS340

  3. Double-Linked Lists • Limitations of a singly-linked list: • Insertion at the front is O(1) • insertion at other positions is O(n) • Insertion is convenient only after a referenced node • Removing a node requires a reference to the previous node • We can traverse the list only in the forward direction • How to overcome these limitations? • Double-linked list CS340

  4. Double-Linked Lists (cont.) CS340

  5. NodeClass private static class Node<E> { private E data; private Node<E> next = null; private Node<E> prev = null; private Node(E dataItem) { data = dataItem; } } CS340

  6. Node Node Node next = = prev data = "Harry" next = null = prev data = "Sam" next = = prev data = "Sharon" Inserting into a Double-Linked List from predecessor sam to predecessor sharon Node<E> sharon = new Node<E>("Sharon"); sharon.next = sam; sharon.prev = sam.prev; sam.prev.next = sharon; sam.prev = sharon;

  7. Node Node Node next = = prev data = "Dick" next = = prev data = "Harry" next = = prev data = "Sharon" Removing from a Double-Linked List harry harry.prev.next = harry.next harry.next.prev = harry.prev CS340

  8. A Double-Linked List Class • A double-linked list object has data fields: • head (a reference to the first list Node) • tail (a reference to the last list Node) • size • Insertion at either end is O(1) • Insertion elsewhere is still O(n) CS340

  9. The LinkedListClass and the Iterator, ListIterator, and Iterable Interfaces CS340

  10. TheLinkedListClass CS340

  11. The Iterator • A moving place marker • Iteratorobject for a list starts at the list head • It can move by calling its next method. • Stays on its current list item until it is needed • An Iterator traverses in O(n) while a list traversal using get() calls in a linked list is O(n2) CS340

  12. IteratorInterface • Defined in java.util CS340

  13. IteratorInterface (cont.) • An Iterator is between elements CS340

  14. IteratorInterface (cont.) • In the following loop, we process all items in List<Integer> through an Iterator Iterator<Integer> iter = aList.iterator(); while (iter.hasNext()) { int value = iter.next(); // Do something with value ... } CS340

  15. Iterators and Removing Elements • remove() deletes the most recent element returned • You must call next()before each remove() • Else IllegalStateExceptionwill be thrown • LinkedList.remove vs. Iterator.remove: • LinkedList.remove must walk down the list each time, then remove,O(n2) complexity • Iterator.remove removes items without starting over at the beginning, O(n) complexity CS340

  16. Iterators and Removing Elements (cont.) • Remove all elements from a list of type Integer that are divisible by a particular value: public static void removeDivisibleBy(LinkedList<Integer> aList, int div) { Iterator<Integer> iter = aList.iterator(); while (iter.hasNext()) { int nextInt = iter.next(); if (nextInt % div == 0) { iter.remove(); } } } CS340

  17. ListIteratorInterface • Iteratorlimitations • Traverses Listonly in the forward direction • Provides a removemethod, but no add method • If you do not want to start from the beginning: • You must advance the Iterator using your own loop • Solution: • ListIteratorextends Iterator CS340

  18. ListIteratorInterface (cont.) • ListIterator is positioned between elements of the list • ListIterator positions: 0 to size CS340

  19. ListIteratorInterface (cont.)

  20. ListIteratorInterface (cont.) CS340

  21. Comparison of IteratorandListIterator • ListIterator is a subinterface of Iterator • Classes that implement ListIterator must provide the features of both • Iterator: • Requires fewer methods • Can iterate over more general data structures • Iterator is required by the Collection interface • ListIteratoris required only by the List interface CS340

  22. Conversion Between ListIteratorand an Index • ListIterator: • nextIndex()returns the index of item to be returned by next() • previousIndex() returns the index of item to be returned by previous() • LinkedList has method listIterator(int index) • Returns a ListIterator positioned so next()will return the item at position index • How? What is the complexity? CS340

  23. Conversion Between ListIteratorand an Index (cont.) CS340

  24. Implementation of a Double-Linked List Class CS340

  25. CS340LinkedList CS340

  26. CS340LinkedList (cont.) import java.util.*; /** Class CS340LinkedList implements a double linked list and a ListIterator. */ public class CS340LinkedList <E> { // Data Fields private Node <E> head = null; private Node <E> tail = null; private int size = 0; . . .

  27. AddMethod • Obtain a reference, nodeRef, to the node at position index • Insert a new Node containing obj before the node referenced by nodeRef To use a ListIterator object to implement add: • Obtain an iterator that is positioned just before the Node at position index • Insert a new Node containing obj before the Node currently referenced by this iterator /** Add an item at the specifiedindex. @param index The index at which the object isto be inserted @param obj The object to beinserted @throws IndexOutOfBoundsException if the index is out of range (i < 0 || i > size()) */ public void add(int index, E obj) { listIterator(index).add(obj); }

  28. GetMethod • Obtain a reference, nodeRef, to the node at position index • Return the contents of the Node referenced by nodeRef /** Get the element at position index. @param index Position of item to be retrieved @return The item at index */ public E get(int index) { return listIterator(index).next(); } CS340

  29. OtherAddandGetMethods public void addFirst(E item) { add(0, item); } public void addLast(E item) { add(size, item); } public E getFirst() { return head.data; } public E getLast() { return tail.data; } CS340

  30. Implementing the ListIteratorInterface • CS340ListIter is an inner class of CS340LinkedListwhich implements the ListIterator interface CS340

  31. Implementing the ListIteratorInterface (cont.) private class CS340ListIter implements ListIterator<E> { private Node <E> nextItem; private Node <E> lastItemReturned; private int index = 0; ... CS340

  32. Constructor public CS340ListIter(inti) { if (i < 0 || i > size) { // Validate i parameter. throw new IndexOutOfBoundsException("Invalid index " + i); } lastItemReturned = null; // No item returned yet. if (i == size) {// Special case of last item index = size; nextItem = null; } else { // Start at the beginning nextItem = head; for (index = 0; index < i; index++) { nextItem = nextItem.next; } } }

  33. ThehasNext()Method • tests to see if nextItem is null public booleanhasnext() { return nextItem != null; } CS340

  34. CS340LinkedList CS340ListIter Node Node Node head tail size 3 nextItem lastItemReturned index 1 next prev null data "Tom" next prev next prev data "Sam" Advancing the Iterator data "Harry" public E next() { if (!hasNext()) { throw new NoSuchElementException(); } lastItemReturned = nextItem; nextItem = nextItem.next; index++; return lastItemReturned.data; } 2

  35. Why is the iterator useful? • Process all elements of a list for(i=0; i < aList.size(); i++){ E nextElement = aList.get(i); } E get(int index){ Node<E> nodeRef = head; for(i=0; i < index; i++){ nodeRef= nodeRef.next(); } } CS340

  36. Why is the iterator useful? (cont.) • Process all elements of a list for(i=0; i < aList.size(); i++){ E nextElement = listIterator(i).get(); } CS340

  37. PreviousMethods public boolean hasPrevious() { return (nextItem == null && size != 0) || nextItem.prev != null; } public E previous() { if (!hasPrevious()) { throw new NoSuchElementException(); } if (nextItem == null) { // Iterator past the last element nextItem = tail; } else { nextItem = nextItem.prev; } lastItemReturned = nextItem; index--; return lastItemReturned.data; }

  38. TheAddMethod • 4 cases to address: • Add to an empty list • Add to the head of the list • Add to the tail of the list • Add to the middle of the list CS340

  39. Adding to an Empty List Node CS340LinkedList next = null = prev data = "Tom" head = null tail = null size = 3 (after insertion) 1 if (head == null) { head = new Node<E>(obj); tail = head; } ... size++ CS340ListIter nextItem = lastItemReturned = null index = 0 1 CS340

  40. Adding to the Head of the List CS340ListIter nextItem = lastItemReturned = null index = 0 1 Node Node Node next = null = prev data = "Tom" next = null = prev data = "Sam" next = = prev data = "Harry" CS340LinkedList head = null tail = null size = 3 4 if (nextItem == head) { Node<E> newNode = new Node<E>(obj); newNode.next = nextItem; nextItem.prev = newNode; head = newNode; } ... size++; index++; Node next = null null = prev data = "Ann" newNode

  41. Adding to the Tail of the List CS340ListIter nextItem = nulllastItemReturned = null index = 2 Node 3 next = = prev data = "Ann" Node Node CS340LinkedList next = null = prev data = "Sam" next = prev = null data = "Tom" head = null tail = null size = 3 4 if (nextItem == null) { Node<E> newNode = new Node<E>(obj); tail.next = newNode; newNode.prev = tail; tail = newNode } ... size++; index++; Node next = null null = prev data = "Bob" newNode

  42. Adding to the Middle of the List CS340ListIter nextItem = nulllastItemReturned = null index = 1 Node 2 next = = prev data = "Ann" Node Node CS340LinkedList next = null = prev data = "Sam" next = prev = null data = "Tom" head = null tail = null size = 3 4 Node else { Node<E> newNode = new Node<E>(obj); newNode.prev = nextItem.prev; nextItem.prev.next = newNode; newNode.next = nextItem; nextItem.prev = newNode; } ... size++; index++; next = null null = prev data = "Bob" newNode

  43. Inner Classes: Static and Nonstatic • CS340LinkedListcontains two inner classes: • Node<E> is static: no need for it to access the data fields of its parent class • CS340ListIter cannot be declared static because its methods access and modify data fields of CS340LinkedList’sparent object which created it • An inner class which is not static: • contains an implicit reference to its parent object • can reference the fields of its parent object CS340

  44. Application of the LinkedListClass If time, use example with eclipse

  45. An Application: Royal Navy • We want to maintain a list of officer’s names in alphabetical order at all times • Create a nested linked list using officers' and ships' information from the British Royal Navy archives. • Each ship in the primary linked list is populated with the correct crew using a second linked list. • The resulting data structure is a linked list of ships, with each node containing a linked list of officers assigned to that ship in 1894.

  46. An Application: Royal Navy • Approach • Develop an OrderedListclass (which can be used for other applications) • Implement a Comparable interface by providing a compareTo(E) method • Use a LinkedList class as a component of the OrderedList • if OrderedList extended LinkedList, the user could use LinkedList's add methods to add an element out of order

  47. Class Diagram for OrderedList

  48. Design

  49. Inserting into an OrderedList • Strategy for inserting new element e: • Find first item > e • Insert e before that item • Refined with an iterator: • Create ListIterator that starts at the beginning of the list • While the ListIterator is not at the end of the list and e >= the next item • Advance the ListIterator • Insert e before the current ListIterator position

  50. Inserting Diagrammed

More Related