CSCI 136: Assignment 5 -- Josephus

Due 3/17/97


For this assignment I would like you to reimplement the Josephus problem by replacing the class CircularVector (which implemented interface Circular) by a new class JosCircularDblyList which should implement the same interface.

Whereas CircularVector relied on an implementation which was a Vector (i.e., there was a field which was a Vector), your class should be based on a CircularDoublyLinkedList class. That is, first write and test a CircularDoublyLinkedList, then use it as a field in JosCircularDblyList. (You will notice that this is the only variant of a linked list which is not included in the structure library provided to you :-)

Both of these classes offer numerous opportunities for logical mistakes, so you should be careful to test CircularDoublyLinkedList class thoroughly before attempting to use it in JosCircularDblyList. Otherwise you will have a very difficult time tracking down where your errors occur.

Unless you sit down and very carefully figure out what the code for the methods in these classes should be (drawing lots of pictures!), you will have little hope of ever getting these to work. In particular, do not expect that just sitting at a keyboard and hacking will work. This program will be a good test of how smart a programmer you really are (and includes lots of code similar to those that will be asked on at least one question on the midterm!)

The code for JosCircularDblyList is even simpler than last time. The key is to understand how next works. Here is the code at the beginning of the class:

 
public class CircularJosList implements Circular 
{
	protected DblyCircularList list = new DblyCircularList();
	
  public synchronized void next()
  {
  	list.rotate();
  }
  ... 
The list is now a doubly-linked circular list. Being circular, it is useful to imagine it as a string of beads, with one bead being held as the head element. The rotate() method corresponds to moving the head over one bead. Thus it does exactly what we want next to do in CircularJosList, so we can identify the current element with the one presently at the head of the list. As a result there is no need to have a special field called current, it is simply the head of the list. Thus adding and removing current elements simply involve changes to the head of the list. You need only ensure that after the operation the head of the list still corresponds with what is supposed to be the current element.

The demo version of this program looks just like the last one, but includes the new implementation. Amazingly, this new implementation seems not to have any erratic behavior like the vector implementation. Go figure!