47
Doubly Linked List Recallthatthe deletion ofan elem entatthe tailisnoteasy because w e have to find the node before the tail(the lastnode)by link hopping. head next elem ent next next next elem ent elem ent elem ent Baltim ore Rom e Seattle Toronto tail roblem can be easily solved by using the double lin - Ed. 2 and 3.: Chapter 4 - Ed. 4: Chapter 3

Doubly Linked List

  • Upload
    tuyet

  • View
    152

  • Download
    1

Embed Size (px)

DESCRIPTION

Doubly Linked List. Ed. 2 and 3.: Chapter 4 Ed. 4: Chapter 3. This problem can be easily solved by using the double linked list. Difference from singly linked lists: -each node contains two links. -two extra nodes: header and trailer, which contain no elements. Class DLNode. - PowerPoint PPT Presentation

Citation preview

Page 1: Doubly Linked List

Doubly Linked List

Recall that the deletion of an element at the tail is not easy because we have to find the node before the tail (the last node) by link hopping.

head

next

element

next nextnext

element element element

Baltimore Rome Seattle Toronto

tail

This problem can be easily solved by using the double linked list.

- Ed. 2 and 3.: Chapter 4- Ed. 4: Chapter 3

Page 2: Doubly Linked List

A node in a doubly linked list: A com pound object that stores a reference to an elem ent and tw o references, called next and prev , to the next and previous nodes, respectively.

Reference tonext node

Reference to anelem ent

next

E lem ent

N ode

Reference toprevious node

prev

Page 3: Doubly Linked List

F o r c o n v e n i e n c e , a d o u b l y l i n k e d l i s t h a s a h e a d e r n o d e a n d a t r a i l e r n o d e . T h e y a r e a l s o c a l l e d s e n t i n e l n o d e s , i n d i c a t i n g b o t h t h e e n d s o f a l i s t .

h e a d e r

B a l t i m o r e R o m e S e a t t l e

t r a i l e r

Difference from singly linked lists:- each node contains two links.- two extra nodes: header and trailer, which contain no

elements.

Page 4: Doubly Linked List

Example:

5050

5060

5080

5070

5090

50A0

50B0

50D0

50C0

50E0

50F0

5110

5100

50C0

5060 50E05080

50D0

50800 next

Rome

Baltimore

Seattle

Node

prev

050500

5050

50A0

5060

0

5070

Element

Page 5: Doubly Linked List

5050

5060

5080

5070

5090

50A0

50B0

50D0

50C0

50E0

50F0

5110

5100

50C0

5060 50E05080

50D0

50800

Rome

Baltimore

Seattle

050500

5050

50A0

5060

0

5070

header

next

Node

prev

Element

Page 6: Doubly Linked List

5050

5060

5080

5070

5090

50A0

50B0

50D0

50C0

50E0

50F0

5110

5100

50C0

5060 50E05080

50D0

50800

Rome

Baltimore

Seattle

050500

5050

50A0

5060

0

5070

header

next

Node

prev

Element

Page 7: Doubly Linked List

5050

5060

5080

5070

5090

50A0

50B0

50D0

50C0

50E0

50F0

5110

5100

50C0

5060 50E05080

50D0

50800

Rome

Baltimore

Seattle

050500

5050

50A0

5060

0

5070

header

next

Node

prev

Element

Page 8: Doubly Linked List

5050

5060

5080

5070

5090

50A0

50B0

50D0

50C0

50E0

50F0

5110

5100

50C0

5060 50E05080

50D0

50800

Rome

Baltimore

Seattle

050500

5050

50A0

5060

0

5070

header

next

Node

prev

Element

Page 9: Doubly Linked List

5050

5060

5080

5070

5090

50A0

50B0

50D0

50C0

50E0

50F0

5110

5100

50C0

5060 50E05080

50D0

50800

Rome

Baltimore

Seattle

050500

5050

50A0

5060

0

5070trailer

header

next

Node

prev

Element

Page 10: Doubly Linked List

Class DLNodeHere is an implementation of nodes for doubly linked lists in Java: public class DLNode { private Object element; private DLNode next, prev; public DLNode() { this( null, null, null ); } public DLNode( Object e, DLNode p, DLNode n ) { element = e; next = n; prev = p; }

Page 11: Doubly Linked List

void setElement( Object newElem ) { element = newElem; } void setNext( DLNode newNext ) { next = newNext; } void setPrev( DLNode newPrev ) { prev = newPrev; } Object getElement() { return element; } DLNode getNext() { return next; } DLNode getPrev() { return prev; } }

Page 12: Doubly Linked List

Insertion of an Element at the Head

B e fo re th e in se r tio n :

h e a d e r

B a lt im o re R o m e S ea t t le

tr a i le r

Page 13: Doubly Linked List

DLNode x = new DLNode();x.setElement(new String(“Toronto”));(x.element = new String(“Toronto”))

Have a new node:

header

Rome Seattle

trailer

Baltimore

Toronto

Page 14: Doubly Linked List

x.setPrev(header);x.setNext(header.getNext());(header.getNext()).setPrev(x);header.setNext(x);

x.prev header;x.next header.next;header.next.prev x;header.next x;

Update the links:

header

Rome Seattle

trailer

Baltimore

Toronto

Page 15: Doubly Linked List

A f t e r t h e i n s e r t i o n :

h e a d e r

R o m e S e a t t l e

t r a i l e r

B a l t i m o r eT o r o n t o

Page 16: Doubly Linked List

Deleting an Element at the Tail

B e f o r e t h e d e l e t i o n :

h e a d e r

R o m e S e a t t l e

t r a i l e r

B a l t i m o r eT o r o n t o

Page 17: Doubly Linked List

((trailer.getPrev()).getPrev()).setNext(trailer);trailer.setPrev((trailer.getPrev()).getPrev());

trailer.prev.prev.next trailer;trailer.prev trailer.prev.prev;

Update the links:

header

Rome

Seattle

trailer

BaltimoreToronto

Page 18: Doubly Linked List

A f t e r t h e d e l e t i o n :

h e a d e r

R o m e

t r a i l e r

T o r o n t o B a l t i m o r e

Page 19: Doubly Linked List

Deleting an element at the head is similar to deleting an element at the tail. Inserting an element at the tail is similar to inserting an element at the head. No link hopping is needed in any of the operations.

However, for inserting a node into the middle of a double linkedlist or deleting a node in the middle, link hopping is always needed.

Page 20: Doubly Linked List

public class NodeList implements List {

protected int numElts; // Number of elements in the list protected DNode header, trailer; // Special sentinels /** Constructor that creates an empty list; O(1) time */ public NodeList() { numElts = 0; header = new DNode(null, null, null); // create header trailer = new DNode(header, null, null); // create trailer header.setNext(trailer); // make header and trailer point to each other } /** Checks if position is valid for this list and converts it to * DNode if it is valid; O(1) time */ public DNode checkPosition(Position p) throws InvalidPositionException { if (p == null) throw new InvalidPositionException

("Null position passed to NodeList");

Page 21: Doubly Linked List

if (p == header)throw new InvalidPositionException ("The header node is not a valid position");

if (p == trailer)throw new InvalidPositionException ("The trailer node is not a valid position");

try { DNode temp = (DNode)p; if ((temp.getPrev() == null) || (temp.getNext() == null))

throw new InvalidPositionException ("Position does not belong to a valid NodeList");

return temp; } catch (ClassCastException e) { throw new InvalidPositionException

("Position is of wrong type for this list"); } }

Page 22: Doubly Linked List

/** Returns the number of elements in the list; O(1) time */ public int size() { return numElts; } /** Returns whether the list is empty; O(1) time */ public boolean isEmpty() { return (numElts == 0); } /** Returns the first position in the list; O(1) time */ public Position first() throws EmptyListException { if (isEmpty()) throw new EmptyListException("List is empty"); return header.getNext(); }

public Position last() throws EmptyContainerException { if (isEmpty())

throw new EmptyContainerException("List is empty"); return trailer.getPrev(); }

Page 23: Doubly Linked List

/** Returns the position before the given one; O(1) time */ public Position prev(Position p) throws InvalidPositionException, BoundaryViolationException { DNode v = checkPosition(p); DNode prev = v.getPrev(); if (prev == header) throw new BoundaryViolationException

("Cannot advance past the beginning of the list"); return prev; } /** Insert the given element before the given position, returning * the new position; O(1) time */ public Position insertBefore(Position p, Object element) throws InvalidPositionException { // DNode v = checkPosition(p); numElts++; DNode newNode = new DNode(v.getPrev(), v, element); v.getPrev().setNext(newNode); v.setPrev(newNode); return newNode; }

Page 24: Doubly Linked List

public Position insertLast(Object element) {numElts++; DNode newNode = new DNode(trailer.getPrev(), trailer, element);// System.out.println(((ONode)newNode.element()).inorderNum()); trailer.getPrev().setNext(newNode); trailer.setPrev(newNode); //trailer.getPrev().setNext(newNode); return newNode; }

public Position insertAfter(Position p, Object element) { DNode v = checkPosition(p); numElts++; DNode newNode = new DNode(v, v.getNext(), element); v.getNext().setPrev(newNode); v.setNext(newNode); return newNode;}

Page 25: Doubly Linked List

/** Insert the given element at the beginning of the list, returning * the new position; O(1) time */ public Position insertFirst(Object element) { numElts++; DNode newNode = new DNode(header, header.getNext(), element); header.getNext().setPrev(newNode); header.setNext(newNode); return newNode; }

Page 26: Doubly Linked List

/**Remove the given position from the list; O(1) time */ public Object remove(Position p) throws InvalidPositionException { DNode v = checkPosition(p); numElts--; DNode vPrev = v.getPrev(); DNode vNext = v.getNext(); vPrev.setNext(vNext); vNext.setPrev(vPrev); Object vElem = v.element(); // unlink the position from the list and make it invalid v.setNext(null); v.setPrev(null); return vElem; }

Page 27: Doubly Linked List

/** Replace the element at the given position with the new element * and return the old element; O(1) time */ public Object replace(Position p, Object element) throws InvalidPositionException { DNode v = checkPosition(p); Object oldElt = v.element(); v.setElement(element); return oldElt; }

public void swapElements(Position a, Position b)throws InvalidPositionException {

//System.out.println("swapElement is executed!!!"); DNode pA = checkPosition(a); DNode pB = checkPosition(b); Object temp = pA.element(); pA.setElement(pB.element()); pB.setElement(temp); }

Page 28: Doubly Linked List

public Position next(Position p) throws InvalidPositionException, BoundaryViolationException { DNode v = checkPosition(p); DNode next = v.getNext(); if (next == trailer) throw new BoundaryViolationException

("Cannot advance past the beginning of the list"); return next; }

public Iterator positions() {return new PositionIterator(this);

} public Iterator elements(){return new PositionIterator(this);}

}

Page 29: Doubly Linked List

Data Structure Exercises 6.1

Page 30: Doubly Linked List

Double-Ended Queues

R e c a l l t h a t a q u e u e h a s a f r o n t a n d a r e a r . E l e m e n t s c a n b e a d d e d a t t h e r e a r a n d c a n b e r e m o v e d a t t h e f r o n t .

F r o n t R e a r

N o w w e a l s o w a n t t o a d d e l e m e n t s a t t h e f r o n t a n d r e m o v e t h e m a t t h e r e a r .

Page 31: Doubly Linked List

Definition: A double-ended queue is a queue that supports insertion and deletion at both the front and the rear of the queue. deque: pronounciated as “deck”

Page 32: Doubly Linked List

The Deque Abstract Data TypeA deque D is an abstract data type that supports the following four fundamental methods: insertFirst(e): Insert a new element e at the beginning of D.

Input: Object; Output: None. insertLast(e): Insert a new element e at the end of D.

Input: Object; Output: None. removeFirst(): Remove and return the first element of D; an

error occurs if D is empty. Input: None; Output: Object

removeLast(): Remove and return the last element of D; an error occurs if D is empty. Input: None; Output: Object

Page 33: Doubly Linked List

Other supporting methods:

first(): Return the first element of D; an error occurs if D is empty Input: None; Output: Object

last(): Return the last element of D; an error occurs if D is empty Input: None; Output: Object

size(): Return the number of elements of D. Input: None; Output: integer

isEmpty(): Determine if D is empty. Input: None; Output: Boolean

Page 34: Doubly Linked List

public interface Deque {void insertFirst(Object e);void insertLast(Object e);Object removeFirst();Object removeLast();Object first();Object last();int size();boolean isEmpty();

Page 35: Doubly Linked List

This table shows a series of operations and their effects. The deque is empty initially.

Operation Output D insertFirst(3) - (3) insertFirst(5) - (5,3) removeFirst() 5 (3) insertLast(7) - (3,7) removeFirst() 3 (7) removeLast() 7 () removeFirst() “error” () isEmpty() true ()

Page 36: Doubly Linked List

Implementing a Deque with a Doubly Linked List

Recall that elements can be inserted and deleted easily at both the head and tail of a doubly linked list. Therefore, a deque can be implemented with a doubly linked list. Example:

header

Rome Seattle

trailer

BaltimoreToronto

Page 37: Doubly Linked List

Class MyDeque

public class MyDeque implements Deque { DLNode header, trailer; int size; public MyDeque() { header = new DLNode(); trailer = new DLNode(); header.setNext( trailer ); trailer.setPrev( header ); size = 0; }

header trailer

Page 38: Doubly Linked List

public Object first() throws DequeEmptyException { if( isEmpty() ) throw new DequeEmptyException( "Deque is empty." ); return header.getNext().getElement(); }

header

Baltimore

link hopping

Page 39: Doubly Linked List

public void insertFirst( Object o ) { DLNode second = header.getNext(); DLNode first = new DLNode( o, header, second ); second.setPrev( first ); header.setNext( first ); size++; }

headersecond

first

Object o

… …header

secondfirst

Object o

Page 40: Doubly Linked List

public Object removeLast() { if( isEmpty() ) throw new DequeEmptyException( "Deque is empty." ); DLNode last = trailer.getPrev(); Object o = last.getElement(); DLNode secondtolast = last.getPrev(); trailer.setPrev( secondtolast ); secondtolast.setNext( trailer ); size--; return o; }

trailersecondtolast last

Object o

trailersecondtolast

last

Object o

Page 41: Doubly Linked List

public Object last() throws DequeEmptyException {if( isEmpty() )throw new DequeEmptyException( "Deque is empty." );

return trailer.getPrev().getElement();}

public void insertLast( Object o ) {DLNode secondLast = trailer.getPrev();DLNode last = new DLNode( o, secondLast, trailer );secondLast.setNext( last );trailer.setPrev( last );size++;}

public int size( ) {return size;}

public boolean isEmpty( ) {return header.getNext() == trailer;}

trailersecondtolast

last

Object o

Page 42: Doubly Linked List

public Object removeFirst() {if( isEmpty() )

throw new DequeEmptyException( "Deque is empty." );DLNode first = header.getNext();Object o = first.getElement();DLNode second = first.getNext();header.setNext( second );second.setPrev( header );size--;return o;}

}public class GenerateDeque {

public static void main(String args[]) {MyDeque D = new MyDeque(); int i;for (i = 0; i < 10; i++) {

D.insertFirst(new Integer(i));}for (i = 0; i < 10; i++)

System.out.print(((Integer) D.removeFirst()).intValue()); }}

headersecondfirst

Page 43: Doubly Linked List

Implementing Stacks and Queues with Deques

Stacks and queues can be easily implemented with a deque. All we need to do is to map the operations. Implementation of a stack with a deque: Stack Method Deque Implementation size() isEmpty() top() push(e) pop()

size() isEmpty() last() insertLast(e) removeLast()

Page 44: Doubly Linked List

Implementation of a queue with a deque: Queue Method Deque Implementation size() isEmpty() front() enqueue(e) dequeue()

size() isEmpty() first() insertLast() removeFirst()

Page 45: Doubly Linked List

Class DequeStack

public class DequeStack implements Stack { private Deque D; public DequeStack() { D = new MyDeque(); } public int size() { return D.size(); } public boolean isEmpty() { return D.isEmpty(); } public void push( Object obj ) { D.insertLast( obj ); }

Page 46: Doubly Linked List

public void top() throws StackEmptyException { try { return D.last(); }

catch( DequeEmptyException ece ) { throw new StackEmptyException( "Stack is empty." ); }

} public Object pop() throws StackEmptyException { try { return D.removeLast(); }

catch( DequeEmptyException ece ) { throw new StackEmptyException( "Stack is empty." ); }

} }

Page 47: Doubly Linked List

Data Structure Exercises 6.2