46
Double-Linked Lists and Circular Lists Click icon to add picture CS340 1

Double-Linked Lists and Circular Lists

  • Upload
    paniz

  • View
    93

  • Download
    0

Embed Size (px)

DESCRIPTION

Double-Linked Lists and Circular Lists. 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 - PowerPoint PPT Presentation

Citation preview

Page 1: Double-Linked Lists and Circular Lists

1

Double-Linked Lists and Circular Lists

Click icon to add picture

CS340

Page 2: Double-Linked Lists and Circular Lists

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

Page 3: Double-Linked Lists and Circular Lists

CS340 3

Double-Linked Lists (cont.)

Page 4: Double-Linked Lists and Circular Lists

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

Page 5: Double-Linked Lists and Circular Lists

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

Page 6: Double-Linked Lists and Circular Lists

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

Page 7: Double-Linked Lists and Circular Lists

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)

Page 8: Double-Linked Lists and Circular Lists

8

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

CS340

Page 9: Double-Linked Lists and Circular Lists

CS340 9

The LinkedList Class

Page 10: Double-Linked Lists and Circular Lists

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)

Page 11: Double-Linked Lists and Circular Lists

CS340 11

Iterator Interface• Defined in java.util

Page 12: Double-Linked Lists and Circular Lists

CS340 12

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

Page 13: Double-Linked Lists and Circular Lists

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

Page 14: Double-Linked Lists and Circular Lists

CS340 14

Iterators and Removing Elementsremove() 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

Page 15: Double-Linked Lists and Circular Lists

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(); } }}

Page 16: Double-Linked Lists and Circular Lists

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

Page 17: Double-Linked Lists and Circular Lists

CS340 17

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

Page 18: Double-Linked Lists and Circular Lists

18

ListIterator Interface (cont.)

Page 19: Double-Linked Lists and Circular Lists

19

ListIterator Interface (cont.)

CS340

Page 20: Double-Linked Lists and Circular Lists

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

Page 21: Double-Linked Lists and Circular Lists

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?

Page 22: Double-Linked Lists and Circular Lists

CS340 22

Conversion Between ListIterator and an Index (cont.)

Page 23: Double-Linked Lists and Circular Lists

23

Implementation of a Double-Linked List Class

Click icon to add picture

CS340

Page 24: Double-Linked Lists and Circular Lists

CS340 24

CS340LinkedList

Page 25: Double-Linked Lists and Circular Lists

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

Page 26: Double-Linked Lists and Circular Lists

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);}

Page 27: Double-Linked Lists and Circular Lists

27

Get Method1. 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

Page 28: Double-Linked Lists and Circular Lists

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

Page 29: Double-Linked Lists and Circular Lists

CS340 29

Implementing the ListIterator Interface• CS340ListIter is an inner class of CS340LinkedList

which implements the ListIterator interface

Page 30: Double-Linked Lists and Circular Lists

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

Page 31: Double-Linked Lists and Circular Lists

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

Page 32: Double-Linked Lists and Circular Lists

CS340 32

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

}

Page 33: Double-Linked Lists and Circular Lists

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"

Page 34: Double-Linked Lists and Circular Lists

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();}

}

Page 35: Double-Linked Lists and Circular Lists

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();}

Page 36: Double-Linked Lists and Circular Lists

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

Page 37: Double-Linked Lists and Circular Lists

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

Page 38: Double-Linked Lists and Circular Lists

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"

Page 39: Double-Linked Lists and Circular Lists

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

Page 40: Double-Linked Lists and Circular Lists

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

Page 41: Double-Linked Lists and Circular Lists

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

Page 42: Double-Linked Lists and Circular Lists

CS340 42

Inner Classes: Static and NonstaticCS340LinkedList 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

Page 43: Double-Linked Lists and Circular Lists

CS340 43

Circular Lists

Click icon to add picture

Page 44: Double-Linked Lists and Circular Lists

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!

Page 45: Double-Linked Lists and Circular Lists

Circular Lists (cont.)

Page 46: Double-Linked Lists and Circular Lists

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