Return to the lecture notes index

Lecture #10 (Monday, February 6, 2006)

LinkedLists

Today we worked on coding LinkedLists. We created a LinkedList.java LinkedList.java

First we want to make the class Node, but since this is a part of LinkedList we want to make the class Node private to LinkedList so we nest it inside. This is so the LinkedList class can access the Node class, but the user or anyother class cannot.

class LinkedList{

// linklist's instance variables would normally be here but for the sake
// of discussion are further down in the class

 private class Node{
 
//what are the two important elements of a node?
// a pointer to the next node, and a reference to the object the node contains 

  private Object item;
  private Node next; 

/*
 *As far as java access protections are concerned the node class has private
 *declarations, but since it is within linkedlist, linkedlist can access node's 
 *private elements.  LinkedList can play with it but we call it private to 
 *show that we dont want linkedlist to play with it directly.
*/

public Node(Object item){
   this.item = item;
   next=null;
 }

//What is the this reference?
//Since there are two variables being refered too as item
//it tells the computer that we want the one that was an instance variable
//for the class instead of the one that was passed in as a parameter. 

 public Node(Object item, Node next){
 this.item= item;
 this. next = next;
 }

//We are going to have accessors and other methods.

 public Node getNext()
 {
	return next;
 }

 public Object getItem()
 { 
	return item;
 }

 public void setNext(Node next)
 {
	this.next=next;
 }

}
// Now we have the basic framework of a node. I did not put in a setItem method
// because there is no reason to set an item on a node. A Node's whole purpose
// is to organize an item. If you need a new item use a new node, if you want 
// to swap items swap nodes. Setting an item within a node would just make
// the code very confusing.

// Now we are going to write contructor for linked list
// these would normally be at the top of the class

private Node head;
private Node tail;
private int count;

// we discussed the general procedures last lecture for creating a linkedlist
Last Lecture


// general constructor
public LinkedList(){
  count=0;
  head = null; 
  tail = null;
}

// one method we need is to be able to add an object at the beginning of the 
//list we do this by an addHead method

public void addHead(Object item){

head = new Node(item, head);// this creates a new node and has it point to head
count++;                    // which was the old start of the list. Then it sets
 			    // head to the new node which becomes the first item
			    // in the list
if(tail==null){  // this is a special case for when the item we are adding will
 tail=head;    // be the first item in the list
 }
}

// addTail adds the new object at the end of the list

public void addTail(Object item)
{
if(tail==null){ //first we take care of the special case where the list is empty
 addHead(item); //addHead changes count
}
else{
Node newNode = new Node(item);  //create a new node
 tail.setNext(newNode);     	// set the tail equal to the new node
 tail = newNode;                //or tail=tail.getNext();
 count++;
 }
}


public Object removeHead(){
if(head==null){  // special case if list is already empty
return null;}

Object newObj = head.getItem();

count--;
head=head.getNext();

 if(count==0){
 tail=null; //
 }

return newObj;
}

public Object removeTail(){
if(tail==null)  // special case if list is empty
return null;

if(count==1){	     // special case if there is only one item in the list
return removeHead(); // removeHead returns to us and we need to bump it up out
                    // of this method
}
//The remove tail is the hardest method we have done so far. We cannot use the
//tail reference because it will not help us because we need to change the one
//in front of it, we need to use a loop and take a walk through the list to get
//there.
 
Node index=head;// we start out with a node pointing to the head;
for(int i = 0; i< (count-1); i++){
 index=index.getNext();              //first we walk through the list (once we
}				     // have delt with the special cases
				     // we want two less than count because 
				     // count is one two high due to indexing
				     // and then we want to be one back from the
				     // last item in the list.

Object temp = tail.getItem();//next we set a tempt to the object we are removing

index.setNext(null);  // then we cut off the rest of the list
tail = index;        // set the tail to the second to last item (index) which is
	             // now the last item in the list
count --;         // decrease the count and finally return the object we removed


return temp;
/* another way to code this is:
*  the general trick is to remember to initialize index outside of the loop
* 
*  Object temp = tail.getItem();
*  Node index;
*  for(index=head; tail != index.getNext(); index=index.getNext())
*  	;
*
*  for an empty for loop you want to put the semicolon directly below
*  the loop because it makes it obvious that the loop is empty
*  forgetting the semicolon would make the next line of code
*  be what is "inside" the for loop
*  
*  index.setNext(null);
*  count--;
*  
*  return temp;
*/

 }
}