Return to the lecture notes index

Lecture #27 (Wednesday, Nov 15, 2006)

LinkedLists

Today we wrote a toString() method, an insertBefore() method and an insertAtN() method. These methods accomplish the same things they did when we wrote them for an array based set, but our implementation will be different.

class LinkedList {


  private class Node {
  
    private Object item;
    private Node next;
    
    public Node (Object item, Node next) {
      this.item = item;
      this.next = next;
    }
    
    public Node (Object item) {
      this.item = item;
      this.next = null;
    }
    
    public Object getItem() { return item; }
    public Node getNext() { return next; }
  
    public void setNext(Node next) { this.next = next; } 
    
    public String toString() {
    
    if (next == null) 
      return "[" + getItem() + ", null]";
    else 
      return "[" + getItem() + ", " + getNext().getItem()  + "]";
    }
    
    public boolean equals (Object o) {
      Node n = (Node) o;
      
      if (!getItem().equals(n.getItem()))
        return false;
    
      if (getNext() != n.getNext()))
          return false;
      }
  
      return true;
  }
  
  
  private Node head;
  private Node tail;
  private int count;
  
  
  public LinkedList() {
    head = tail = null;
    count = 0;
  }

  
  public void addFirst(Object o) {
    head = new Node (o, head);
    
    if (tail == null)
      tail = head;
      
    count++;
  }
  
  
  public void addLast(Object o) {
    
    if (tail == null) {
      addFirst(o);
      // count is increased by addFirst()
      return;
    }
    
    tail.setNext(new Node (o, null));
    tail = tail.getNext();
    count++;
  }
  
  
  public Object getNth (int n) {
    int posn;
    Node index;
    
    if (n > count)
      return null;
    
    for (index=head, posn=0; (posn < n); index=index.getNext(), posn++)
    ;
      
    return index.getItem();   
  }
  
  
  public boolean insertBefore (Object insertMe, Object beforeMe) {
  
    // Empty list -- nothing to do
    if (head == null) return false;
    
    // Before the head -- head reference is predecessor
    if (head.getItem().equals(beforeMe)) {
     addFirst(insertMe);      
     return true;
    }
    
    // Look ahead by one for "beforeMe"
    // Stop when the next node contains the item beforeMe
    // Then we change the next reference of the node we're in to a
    // new node containing the item to insert and a next reference to
    // the node with beforeMe in it.
    Node index;
    for (index=head; index.getNext() != null; index = index.getNext()) {
      if (index.getNext().getItem().equals(beforeMe) {
        index.setNext(new Node(insertMe, index.getNext()));
        count++;
        return true;
      }
    }
    
    return false;
  
  }
    
  // Walk through our list adding each item, as long as the node
  // we're at is not null
  public String toString() {
    String s = "";
    
    for (Node index=head; index != null; index=index.getNext())
      s += index.getItem().toString();
    
    return s;
  }
  
  // We count items beginning with 0
  // Return false if (n<0) or if (n>count)
  public boolean insertAtN(Object insertMe, int n){
    if(n > count || n < 0){             
        return false;
    }
    if(n==0){
        addFirst(insertMe);
        return true;
    }
    if(n == count){
        addLast(insertMe);
        return true;
    }
    Node index = head;
    for(int x=0; x<(n-1); x++){             // Index will end up being the (n-1)th item
        index = index.getNext();
    }
    
    index.setNext(new Node(insertMe, index.getNext()));
    count ++;
    return true;
}

}