480 likes | 930 Views
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.
E N D
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.
Have a new node: header trailer Baltimore Rome Seattle Toronto DLNode x = new DLNode(); x.setElement(new String(“Toronto”)); (x.element new String(“Toronto”))
Update the links: trailer header Baltimore Rome Seattle Toronto 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: trailer header Toronto Baltimore Rome Seattle ((trailer.getPrev()).getPrev).setNext(trailer); trailer.setPrev((trailer.getPrev()).getPrev()); trailer.prev.prev.next trailer; trailer.prev trailer.prev.prev;
However, for inserting a node into the middle of a double linked list or deleting a node in the middle, link hopping is always needed.
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");
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"); } }
/** 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(); }
/** 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; }
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;}
/** 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; }
/**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; }
/** 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); }
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);} }
public interface Deque { void insertFirst(Object e); void insertLast(Object e); Object removeFirst(); Object removeLast(); Object first(); Object last(); int size(); boolean isEmpty(); }
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
public Object first() throws DequeEmptyException { if( isEmpty() ) throw new DequeEmptyException( "Deque is empty." ); return header.getNext().getElement(); } link hopping header Baltimore
second header first Object o public void insertFirst( Object o ) { DLNode second = header.getNext(); DLNode first = new DLNode( o, header, second ); second.setPrev( first ); header.setNext( first ); size++; } first second header … … … Object o
secondtolast trailer secondtolast last trailer … last Object o Object o 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 ); secondtol ast.setNext( trailer ); size -- ; return o; } …
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;} secondtolast trailer … last Object o
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()); } } first second header …