Double Linked Lists
Today we are going to make for ourselves the rest of a double linked list. DoublyLinkedList.java
Lets start with the addFirst, we need to realize that our constructor for node is different. So first we changed the constructor for newNode to include the prev reference. We also need to set the prev reference on the old head to the new head.
public void addFirst(Object item){ head = new Node(null, item, head); // here we use the new constructor head.getNext().setPrev(head); // here we set the prev reference on the old head count++; if(tail==null){ tail=head; } // next we change addLast and we need to have that reference coming backwards // from the new tail to the old tail, as well as the change in the constructor public void addLast(Object item){ if(tail==null){ addFirst(item); return; } Node newNode = new Node( tail, item, null); // we changed the node constructor tail.setNext(newNode); // moved the reference tail = newNode; // tail = tail.getNext(); count++; } // now lets look at removeFirst // we are removing the head so we need to change the second item (new head) // prev pointer back to null public Object removeFirst(){ // pecial case stays the same if (count == 0) return null; Object savedItem = head.getItem(); head = head.getNext(); // new line of code head.setPrev(null); count --; if ( count == 0 ) tail = null; return savedItem; } // now lets tackle removeLast // now remember we can now traverse forwards and backwards so the removeLast // method changes a lot. The while loop can leave. public Object removeLast(){ // special cases are still the same if (count == 0) return null; if (count == 1){ return removeFirst(); } // code we are more concerned iwth Node index = tail.getPrev(); // this is different we used to have to walk t // through a while loop Object savedItem = tail.getItem(); index.setNext(null); tail = index; count --; return savedItem; } // removeNth we are still going to start at the head and move forward like I // did before. I can now stop at position N or the position before it // now we are going to stop at N for readability public Object removeNth(long n){ //special case are still the same if (count == 0) return null; if ( n == 0 ) return removeFirst(); if (n == (count-1)) return removeLast(); // we changed this loop so that we stop at n, it makes the code more readable for (long index = 0; index < n; posn = posn.getNext()) ; Object tempObj = posn.getItem(); // the remove also changed, we stand on n and get the one before it and // make its pointer point to the one after n posn.getPrev.setNext(posn.getNext()); // we stand at n and get the one after n and make it point to the one // before n posn.getNext.setPrev(posn.getPrev()); count --; return tempObj; } // now we are doing the removeObject. We can change the while loop to stop // at right on top of the item we are looking for. Lets do it for readability public void removeObject (Object item) { // special cases should be the same removeHead removeTail if the list is empty // I will not include it here, the special cases are here in the java file Node index = head; //we changed the parameters of this while loop for readability. We now can // stop on the item we are going to remove while( (index != tail) && (!index.getItem().equals(item)) ) index = index.getNext(); // the last special case we had to deal with, if it was not in the list if( index == tail) return; // if it is in the list then we can do the same pointer move that we did // for the removeNth index.getPrev().setNext(index.getNext()); index.getNext().setPrev(index.getPrev()); count --; } // now we are about to go work on the iterator method and we only had to change // the name from LinkedListIterator to DoublyLinkedListIterator public Iterator iterator(){ return new DoublyLinedListIterator(this); } // so lets go change our LinkedListIterator class public class DoublyLinkedListIterator implements Iterator{ private DoublyLinkedList ll; private Node index; public DoublyLinkedListIterator( DoublyLinkedList ll) { this.ll = ll; index = null; } // other methods stay the same // we only need to change the insert // the new Node needs to have a pointer to prev // also something needs to point to the new Node index public void insert (Object o){ // we change the constructor to handle the new parameter index.setnext (new Node(index, o, index.getNext()) ); if(index.getNext() != null) // we change the prev pointer so it is still accurate index.getNext().setPrev(index); ll.coun++; index = index.getNext(); } }