Programming Assignment 2 Checklist: Randomized Queues and Dequeues
Programming Assignment 2 Checklist: Randomized Queues and Dequeues
htm #1
Should I use arrays or linked lists in my implementations? In general we don't tell you how to implement your data structures—you can
use arrays, linked lists, or maybe even invent your own new structure provide you abide by the specified time and space requirements. So,
before you begin to write the code, make sure that your data structure will achieve the required resource bounds.
How serious are you about not calling any library function other than Std* or Integer.parseInt()? You will receive a substantial
deduction. Of course, you will need to import the java.util.Iteratorinterface.
What is meant by uniformly at random? If there are N items in the randomized queue, then you should choose each one with probability
1/N, up to the randomness of StdRandom.uniform(), independent of past decisions. You can generate a pseudo-random integer between
0 and N-1 using StdRandom.uniform(N)from the StdRandom.java library.
Given an array, how can I rearrange the entries in random order? Use StdRandom.shuffle()— it implements the Knuth shuffle
discussed in lecture and runs in linear time.
What should the remove() method in my iterator do if it is not supported? What should the next() method return if the iterator has no
more items? According to the API for the Iterator interface, remove() should throw an
java.lang.UnsupportedOperationExceptionand next() should throw a java.util.NoSuchElementException.
What should my deque (or randomized queue) iterator do if the deque (or randomized queue) is structurally modified at any time after
the iterator is created (but before it is done iterating)?You don't need to worry about this in your solution. An industrial-strength solution
(used in the Java libraries) is to make the iterator fail-fast: throw a java.lang.ConcurrentModificationExceptionas soon as this is
detected.
Can I add extra public methods to the Deque or RandomizedQueueAPIs? Can I use different names for the methods? No, you must
implement the API exactly as specified. The only exception is the main() method, which you should use for unit testing.
Why does the following code lead to a generic array creationcompile-time error whenItem is a generic type parameter?
Java prohibits the creation of arrays of generic types. See the Q+A in Section 1.3 for a brief discussion. Instead, use a cast.
The compiler says that my program uses unchecked or unsafe operations and to recompile with -Xlint:unchecked for details.Usually this
means you did a potentially unsafe cast. When implementing a generic stack with an array, this is unavoidable since Java does not allow
generic array creation. For example, the compiler outputs the following warning with ResizingArrayStack.java:
% javac ResizingArrayStack.java
Note: ResizingArrayStack.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Checkstyle complains that my nested class' instance variables must be private and have accessor methods.are not private. Do I need
to make them private? No, but there's no harm in doing so. The access modifier of a nested class' instance variable is irrelevant—regardless
of its access modifiers, it can be accessed anywhere in the file. (Of course, the enclosing class' instance variables should be private.)
Will I lose points for loitering?Yes. Loitering is maintaining a useless to an reference to an object that could otherwise be garbage
collected.
These are purely suggestions for how you might make progress. You do not have to follow these steps. These same steps apply to both of
the data structures that you will be implementing.
1. Make sure you understand the constraints for Deque and RandomizedQueue. Your Deque should use space proportional to the
number of items currently in the deque, and each operation must complete in constant worst-case time . Your Deque iterator must
support each iteration operation (including construction) in constant worst-case time , and use a constant amount of extra space per
iterator. Your RandomizeQueue should use space proportional to the number of items currently in the queue, and each operation
should complete in constant amortized time. Your RandomizedQueue iterator implementation must support each iteration
operation (excluding construction) in constant worst-case time , and use a linear amount of extra space per iterator. Every detail in
these constraints is important. Do not proceed until you understand them.They are summarized in the table below.
2. Decide whether you want to use an array, linked list, or your own class. This choice should be made based on the constraints
discussed above. You may make different choices for Deque and RandomizedQueue. You might start by considering why a resizing
array does not support constant worst-case time operations in a Stack.
3. Use our example programs as a guide when implementing your methods.There are many new ideas in this programming
assignment, including resizing arrays, linked lists, iterators, the foreach keyword, and generics. If you are not familiar with these
topics, our example code should make things much easier. ResizingArrayStack.java uses a resizing array; Stack.java uses a singly-linked
list. Both examples use iterators, foreach, and generics.
4. We strongly recommend that you develop unit tests for your code as soon as you've written enough methods to allow for
testing. As an example for Deque, you know that if you call addFirst() with the numbers 1 through N in ascending order, then call
removeLast() N times, you should see the numbers 1 through N in asending order. As soon as you have those two methods written,
you can write a unit test for these methods. Arguably even better are randomized unit tests (which we employ heavily in our
correctness testing). We recommend that you create a client class with a name like TestDeque, where each unit test is a method in
this class. Don't forget to test your iterator.
1. For this assignment, it is very important that you carefully plan your implementation before you begin.In particular, for each
data structure that you're implementing ( RandomizedQueueand Deque), you must decide whether to use a linked list or an array (or
your own custom class if you prefer). Your decision should be made so that you obey the timing and space limits given in the
specification. If you make the wrong choice, you will have to abandon your code.
2. Make sure that your memory use is linear in the current number of items, as opposed to the greatest number of items that has
ever been in the data structure since its instantiation.If you're using a resizing array, you must downsize when the array becomes
sufficiently empty. You must also take care to avoid loitering anytime you remove an item.
3. Make sure to test what happens when your data structures are emptied. One very common bug is for something to go wrong
when your data structure goes from non-empty to empty and then back to non-empty. Make sure to include this in your tests.
4. Make sure to test that multiple iterators can be used simultaneously. This can be done with a nested foreach loop. The iterators
should operate independently of each other.
5. Don't rely on our automated tests for debugging.You don't have access to the source code of our testing suite, so the Assessment
Details may be hard to utilize for debugging. As suggested above, write your own unit tests; it's good practice.
6. If you use a linked list, you might consider using a sentinel node (or nodes).Sentinel nodes will simplify your code and reduce
susceptibility to bugs. However, they are not required, particularly since we do not provide examples which feature sentinel nodes.