Double- Linked Lists and Circular Lists CS340 1. Double-Linked Lists Limitations of a singly-linked...

Preview:

Citation preview

1

Double-Linked Lists and Circular Lists

Click icon to add picture

CS340

CS340 2

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

Double-Linked Lists (cont.)

CS340 4

Node Classprivate static class Node<E> { private E data; private Node<E> next = null; private Node<E> prev = null;

private Node(E dataItem) { data = dataItem; }}

5

Inserting into a Double-Linked List

next = = prevdata = "Harry"

Node

next = null = prevdata = "Sam"

Node

next = = prevdata = "Sharon"

Node

Node<E> sharon = new Node<E>("Sharon");

sharon.next = sam;

sharon.prev = sam.prev;

sam.prev.next = sharon;

sam.prev = sharon;

from predecessor

to predecessor

sam

sharon

CS340 6

Removing from a Double-Linked List

next = = prevdata = "Dick"

Node

next = = prevdata = "Harry"

Node

next = = prevdata = "Sharon"

Nodeharry

harry.prev.next = harry.nextharry.next.prev = harry.prev

CS340 7

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)

8

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

CS340

CS340 9

The LinkedList Class

CS340 10

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(n2)

CS340 11

Iterator Interface• Defined in java.util

CS340 12

Iterator Interface (cont.)• An Iterator is between elements

CS340 13

Iterator Interface (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 14

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(n2) complexity Iterator.remove removes items without starting over at the

beginning, O(n) complexity

CS340 15

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 16

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

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

18

ListIterator Interface (cont.)

19

ListIterator Interface (cont.)

CS340

CS340 20

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

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

Conversion Between ListIterator and an Index (cont.)

23

Implementation of a Double-Linked List Class

Click icon to add picture

CS340

CS340 24

CS340LinkedList

25

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; . . .

26

Add Method1. Obtain a reference, nodeRef, to

the node at position index2. Insert a new Node containing

obj before the node referenced by nodeRef

To use a ListIterator object to implement add:

3. Obtain an iterator that is positioned just before the Node at position index

4. 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 < 0 || i > size())*/public void add(int index, E obj) { listIterator(index).add(obj);}

27

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

CS340 28

Other Add and Get Methodspublic 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 29

Implementing the ListIterator Interface

• CS340ListIter is an inner class of CS340LinkedList which implements the ListIterator interface

CS340 30

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

31

Constructorpublic CS340ListIter(int i) { 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; } }}

CS340 32

The hasNext()Method

• tests to see if nextItem is nullpublic boolean hasnext() {return nextItem != null;

}

Advancing the Iterator33

CS340LinkedList

head tail size 3

next prev nulldata "Tom"

Node

next prev

Node

next prevdata "Sam"

Node

public E next() { if (!hasNext()) { throw new NoSuchElementException(); } lastItemReturned = nextItem; nextItem = nextItem.next; index++; return lastItemReturned.data;}

CS340ListIter

nextItem lastItemReturned index 12

data "Harry"

CS340 34

Why is the iterator useful?• Process all elements of a listfor(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 35

Why is the iterator useful? (cont.)• Process all elements of a listfor(i=0; i < aList.size(); i++){

E nextElement = listIterator(i).get();}

36

Previous Methodspublic 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;}

CS340 37

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

Adding to an Empty List

if (head == null) { head = new Node<E>(obj); tail = head;}...size++

(after insertion)

CS340ListIter

nextItem = lastItemReturned = null index = 01

CS340LinkedList

head = nulltail = nullsize = 31

Node

next =null = prevdata = "Tom"

39

Adding to the Head of the List

Node

next =null = prevdata = "Tom"

CS340ListIter

nextItem = lastItemReturned = null index = 0

if (nextItem == head) { Node<E> newNode = new Node<E>(obj); newNode.next = nextItem; nextItem.prev = newNode; head = newNode;}...size++;index++;

CS340LinkedList

head = nulltail = nullsize = 3

1Node

next = = prevdata = "Harry"

Node

next = null = prevdata = "Sam"

4

next = nullnull = prevdata = "Ann"

Node

newNode

40

Adding to the Tail of the List

Node

next =prev = nulldata = "Tom"

CS340ListIter

nextItem = nulllastItemReturned = null index = 2

if (nextItem == null) { Node<E> newNode = new Node<E>(obj); tail.next = newNode; newNode.prev = tail; tail = newNode}...size++;index++;

CS340LinkedList

head = nulltail = nullsize = 3

3 Node

next = = prevdata = "Ann"

Node

next = null = prevdata = "Sam"

4

next = nullnull = prevdata = "Bob"

Node

newNode

Adding to the Middle of the List

Node

next =prev = nulldata = "Tom"

CS340ListIter

nextItem = nulllastItemReturned = null index = 1

else { Node<E> newNode = new Node<E>(obj); newNode.prev = nextItem.prev; nextItem.prev.next = newNode; newNode.next = nextItem; nextItem.prev = newNode;}...size++;index++;

CS340LinkedList

head = nulltail = nullsize = 3

2 Node

next = = prevdata = "Ann"

Node

next = null = prevdata = "Sam"

4

next = nullnull = prevdata = "Bob"

Node

newNode

CS340 42

Inner Classes: Static and Nonstatic

CS340LinkedList contains 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’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

Circular Lists

Click icon to add picture

CS340 44

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!

Circular Lists (cont.)

CS340 46

Circular Lists (cont.)

next = = prevdata = "Sharon"

Node

next = = prevdata = “Helen"

Node

next = = prevdata = “Harry"

Node

next = = prevdata = “Tom"

Node

head =tail =size = 4

Linked List

Recommended