Mega Code Archive

 
Categories / Java / Collections Data Structure
 

Doubly Linked list

/*****************************************************************************  * Copyright (C) The Apache Software Foundation. All rights reserved.        *  * ------------------------------------------------------------------------- *  * This software is published under the terms of the Apache Software License *  * version 1.1, a copy of which has been included with this distribution in  *  * the LICENSE file.                                                         *  *****************************************************************************/ /**  * A simple Doubly Linked list class, designed to avoid  * O(n) behaviour on insert and delete.  */ public class DoublyLinkedList {     /**      * Basic doubly linked list node interface.      */   public static class Node {     private Node next = null;     private Node prev = null;            public final Node getNext() { return next; }     public final Node getPrev() { return prev; }                  protected final void setNext(Node newNext) { next = newNext; }     protected final void setPrev(Node newPrev) { prev = newPrev; }         /**          * Unlink this node from it's current list...          */     protected final void unlink() {       if (getNext() != null)         getNext().setPrev(getPrev());       if (getPrev() != null)         getPrev().setNext(getNext());              setNext(null);       setPrev(null);     }                      /**          * Link this node in, infront of nde (unlinks it's self          * before hand if needed).          * @param nde the node to link in before.          */     protected final void insertBefore(Node nde) {       // Already here...       if (this == nde) return;       if (getPrev() != null)                 unlink();              // Actually insert this node...       if (nde == null) {         // empty lst...         setNext(this);         setPrev(this);       } else {         setNext(nde);         setPrev(nde.getPrev());         nde.setPrev(this);                 if (getPrev() != null)                     getPrev().setNext(this);       }     }   }     private Node head = null;     private int  size = 0;            public DoublyLinkedList() {}            /**      * Returns the number of elements currently in the list.      */     public synchronized int getSize() { return size; }     /**      * Removes all elements from the list.      */     public synchronized void empty() {         while(size > 0) pop();     }            /**      * Get the current head element      * @return The current 'first' element in list.      */     public Node getHead() { return head; }     /**      * Get the current tail element      * @return The current 'last' element in list.      */     public Node getTail() { return head.getPrev(); }     /**      * Moves <tt>nde</tt> to the head of the list (equivilent to      * remove(nde); add(nde); but faster.      */     public void touch(Node nde) {         if (nde == null) return;         nde.insertBefore(head);         head = nde;     }     /**      * Adds <tt>nde</tt> to the head of the list.      * In perl this is called an 'unpop'.  <tt>nde</tt> should      * not currently be part of any list.      * @param nde the node to add to the list.      */     public void add(Node nde) {         if (nde == null) return;         nde.insertBefore(head);         head = nde;         size++;     }        /**      * Removes nde from the list it is part of (should be this      * one, otherwise results are undefined).  If nde is the      * current head element, then the next element becomes head,      * if there are no more elements the list becomes empty.      * @param nde node to remove.      */     public void remove(Node nde) {         if (nde == null) return;         if (nde == head) {             if (head.getNext() == head)                  head = null;  // Last node...             else                 head = head.getNext();         }         nde.unlink();         size--;     }     /**      * Removes 'head' from list and returns it. Returns null if list is empty.      * @returns current head element, next element becomes head.      */     public Node pop() {         if (head == null) return null;                Node nde = head;         remove(nde);         return nde;     }     /**      * Removes 'tail' from list and returns it. Returns null if list is empty.      * @returns current tail element.      */     public Node unpush() {         if (head == null) return null;                Node nde = getTail();         remove(nde);         return nde;     }     /**      * Adds <tt>nde</tt> to tail of list      */     public void push(Node nde) {         nde.insertBefore(head);         if (head == null) head = nde;         size++;     }     /**      * Adds <tt>nde</tt> to head of list      */     public void unpop(Node nde) {         nde.insertBefore(head);         head = nde;         size++;     } }