Search code examples
javalisthyperlinkcircular-list

Implementing a Circular Link List in Java


I am trying to create a Circular Link list based on the following: The only access to the list is a single reference, current, that can point to any link on the list and can move around the list as needed. The list should handle insertion, searching and deletion: these operations take place one link downstream of the link pointed to by current. Be able to display the list.

1) The data members of class circular linked list should include the reference current and a variable to track the size of links in the circular list.

2) The methods needed to define in the class circular include:

• insert: insert after current link • delete: delete one beyond current • find: find link with given key • deleteKey: delete link with given key • displayList: display the list (all the links in the list) • step: move current to the next link • peek: return the data stored in current • isEmpty: check whether the list is empty

Here is my current code (right now it is linear - haven't made it circular yet):

public class CircularList<T> {
private Link current;            // ref to the current link in the list
private int nLinks;             //Reference to number of links in the list 

//--------------------------------------------------------------
public CircularList()          // constructor
{
    current = null;
    nLinks = 0;

}   //End constructor method - CircularList()

// -------------------------------------------------------------
public void insert(long dd)
{   
    Link newLink = new Link(dd);    // make new link
    if (nLinks == 0) 
    {
        current = newLink;
        nLinks++;
    }

    if(nLinks != 0) 
    {         
        current.next = newLink;            // current --> newLink
        newLink = current; 
        nLinks++;
    }
}   //End insert()
// --------------------------------------------------------------
public Link delete()      // delete link after current
{              
    Link temp = null;
    if(nLinks == 0)     //first check whether the list is empty
        return null;
    if(nLinks != 0)
    {
        temp = current.next;            // save reference to link
        current = current.next;             // delete it: current-->one after current
        nLinks--;

    }
    return temp;                        // return deleted link
}   //End delete()


// -------------------------------------------------------------
public void displayList()
{
    System.out.print("List: ");
    int tempLinks = nLinks;
    while(tempLinks > 0)      // until end of list
    {
        current.displayLink();      // print data
        tempLinks--;                    // decrement nLinks
        current = current.next;     // move to next link
    }
    System.out.println("");
}   //End displayList()
// -------------------------------------------------------------
public boolean isEmpty()       // true if list is empty
    {
    return (current==null);
}   //End isEmpty() 
// -------------------------------------------------------------
public void step() //Move current to next Link
{
    current = current.next;
}   //End step()
}   //End CircularList Class

When it runs I get a null pointer exception. (I am thinking there is something wrong with my insert method to cause this issue when I try to call the display method) I am pretty sure it is not inserting all 4 links properly. When I try to display it, it only displays the data 2 and 8, which are the first and last items inserted.

My link class:

public class Link {

   public long dData;                 // data item
   public Link next;                  // next link in list

// -------------------------------------------------------------
   public Link(long d)                // constructor
   {
       dData = d;
       next = null;
   }
// -------------------------------------------------------------
   public void displayLink()          // display this link
   { 
       System.out.print(dData + " "); 
   }
// -------------------------------------------------------------

}   //End Link Class

My App class:

public class CircularLinkListApp {
public static void main(String[] args) {
    CircularList theList = new CircularList();  // make new list

    theList.insert(2);      // insert four items
    theList.insert(4);
    theList.insert(6);
    theList.insert(8);

    theList.displayList();              // display list

  while( !theList.isEmpty() )         // until it's empty,
  {
     Link aLink = theList.delete();   // delete link
     System.out.print("Deleted ");         // display it
     aLink.displayLink();
     System.out.println("");
  }
  theList.displayList();              // display list

} // end of main()
}   //End CircularLinkListApp class

Solution

  • It seems that all the problems you are facing are because you did not take the time to think about what you code will have to do on paper. I assure you that if you start drawing your list on paper, with cases for the links and arrows to represent the .next properties it will suddenly become more obvious what behavior you need to code

    1. The insert problem

    The first and most obvious problem you will face is your insert method.

    Case no links already

    this one is fine, even though you could add one more line to make it circular already, it would be better.

    Case with links already in the list

    This is where problems starts. The exercise ask you to add the link after the current one. It starts well with current.next = newLink; but the next line newLink = current; doesn't do anything for you as it is only assigning the value of current to newLink.

    A second problem to take in consideration is that you never check if current don't already have a next link. If it does then your code will effectively detach any and all Links linked to the current link. Find a solution to verify if next is already set and if yes you need to find a way to insert the new link between the two existent links.

    The circularity

    I feel that the fact that is it circular scares you. It really shouldn't. Even with only one item you can be circular. In this case current.next will be the same as current that's all. You already have a variable to know how many elements you have so just rely on that to know what to do. In fact, once it will be coded correctly you will never have a .next equal to null. The only exception being when the list is empty current will be equals to null (even though you can avoid this too but it is not necessary)

    2. The displayList problem

    Here is where you need your list to be circular. You have the right idea but since you are not having a circular list eventually one of the current.next will point at null, hence your original problem. If you fix your circularization and insert the display will work at least the first after the inserts

    3. The delete problem

    The assignement is to delete the next item in the list. You start well with storing in a temporary variable the element you are going to delete but you're missing some points :

    1. current = current.next; means that you are loosing your actual current. This is not what you are wanting to do. Firstly your "cursor" should not move. And secondly current.next at this point is the item you want to remove from the list.
    2. You need to think a bit more about all you need to do in order to cut away a link. You need to detatch the current.next reference to the item you're removing and attach it to the item appearing after the one you are removing.

    I hope I've been clear. There are plenty of little quirks that I won't mention primarily because they don't affect functionality, they are just piece of code that could be re-written in a better, clearer way.