Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture Objectives  Linked list data structures:  Singly-linked (cont.)  Doubly-linked  Circular  Implementing the List interface as a linked list.

Similar presentations


Presentation on theme: "Lecture Objectives  Linked list data structures:  Singly-linked (cont.)  Doubly-linked  Circular  Implementing the List interface as a linked list."— 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 1

2 Double-Linked Lists and Circular Lists CS340 2

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 3

4 Double-Linked Lists (cont.) CS340 4

5 Node Class private static class Node { private E data; private Node next = null; private Node prev = null; private Node(E dataItem) { data = dataItem; } CS340 5

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

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

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 8

9 The LinkedList Class and the Iterator, ListIterator, and Iterable Interfaces 9 CS340

10 The LinkedList Class CS340 10

11 The Iterator  A moving place marker  Iterator object 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(n 2 ) CS340 11

12 Iterator Interface  Defined in java.util CS340 12

13 Iterator Interface (cont.)  An Iterator is between elements CS340 13

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

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

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 aList, int div) { Iterator iter = aList.iterator(); while (iter.hasNext()) { int nextInt = iter.next(); if (nextInt % div == 0) { iter.remove(); } CS340 16

17 ListIterator Interface  Iterator limitations  Traverses List only in the forward direction  Provides a remove method, but no add method  If you do not want to start from the beginning: You must advance the Iterator using your own loop  Solution:  ListIterator extends Iterator CS340 17

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

19 ListIterator Interface (cont.) 19

20 ListIterator Interface (cont.) CS340 20

21 Comparison of Iterator and ListIterator  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  ListIterator is required only by the List interface CS340 21

22 Conversion Between ListIterator and 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 22

23 Conversion Between ListIterator and an Index (cont.) CS340 23

24 Implementation of a Double-Linked List Class 24 CS340

25 CS340LinkedList CS340 25

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

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

28 Get Method 1. Obtain a reference, nodeRef, to the node at position index 2. 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 28

29 Other Add and Get Methods 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; } 29 CS340

30 Implementing the ListIterator Interface  CS340ListIter is an inner class of CS340LinkedList which implements the ListIterator interface CS340 30

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

32 Constructor 32 public CS340ListIter(int i) { if (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 The hasNext() Method  tests to see if nextItem is null public boolean hasnext() { return nextItem != null; } CS340 33

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

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 nodeRef = head; for(i=0; i < index; i++){ nodeRef = nodeRef.next(); } CS340 35

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 36

37 Previous Methods 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; } 37

38 The Add Method  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 38

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

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

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

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

43 Inner Classes: Static and Nonstatic  CS340LinkedList contains two inner classes:  Node 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 ’s parent 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 43

44 Application of the LinkedList Class 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 OrderedList class (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

51 Inserting Diagrammed (cont.)

52 OrderedList.add public void add (E e) { ListIterator iter = theList.listIterator(); while (iter.hasNext()) { if (e.compareTo(iter.next()) < 0) { // found element > new one iter.previous(); // back up by one iter.add(e); // add new one return; // done } iter.add(e); // will add at end }

53 Using Delegation to Implement the Other Methods public E get (int index) { return theList.get(index); } public int size () { return theList.size(); } public E remove (E e) { return theList.remove(e); } // returns an iterator positioned before the first element public Iterator iterator() { return theList.iterator(); }

54 Circular Lists 54 CS340

55 Circular Lists  Circular double-linked list:  Link last node to the first node, and  Link first node to the last node  We can also build singly-linked circular lists:  Traverse in forward direction only  Advantages:  Continue to traverse even after passing the first or last node  Visit all elements from any starting point  Never fall off the end of a list  Disadvantage: Code must avoid an infinite loop! CS340 55

56 Circular Lists (cont.)

57 CS340 57 next = = prev data = "Sharon" Node next = = prev data = “Helen" Node next = = prev data = “Harry" Node next = = prev data = “Tom" Node head = tail = size = 4 Linked List


Download ppt "Lecture Objectives  Linked list data structures:  Singly-linked (cont.)  Doubly-linked  Circular  Implementing the List interface as a linked list."

Similar presentations


Ads by Google