return index of lecture notes

Lecture #11 (July 18, 2006)

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