If we implement an ordered list as an array, inserting a new element may require shifting a large fraction of the old elements, in order to create a "hole" for the new element in the right place. In this discussion we're going to look at a scheme to prevent or defer some of this work, by prepositioning holes in the array so that new elements can fill them.

We are going to define a new generic class `HoleyList<T>`

,
which will implement L&C's interface `OrderedListADT<T>`

(though we won't deal with all the required methods here). An object of type
`HoleyList<T>`

will store elements of type `T`

in an array of type `T [ ]`

, but the array will contain both
elements and `null`

entries called "empty slots". The empty slots
may occur between real entries. The class also has a field ```
int size
```

for the number of real elements being stored.

Given an array of length n, full of `T`

elements, we construct a
`HoleyList`

by creating an array of length 2n, then placing the
elements in the *even-numbered* positions -- the first in entry 0, the
second in entry 2, and so on, so that the last real element goes in entry 2n -
2 and entry 2n - 1 (like all other odd-numbered entries) is `null`

.

Removing an element from a `HoleyList`

is simple -- we replace
its entry with `null`

and don't move any other elements or
otherwise change the array at all. The `add`

operation is more
interesting. To add a new element `y`

, we first find the largest
element `x`

that is less than `y`

in the natural order.
(There is a special case if there is no such element, but it is quite similar.)
We want to put `y`

in the slot immediately after `x`

:

- If the slot immediately after
`x`

is empty, we just put`y`

there and we are done. - If that slot is full, we find the next empty slot in the list, if any.
We shift the elements between
`x`

and that slot each forward by one entry, making an empty slot right after`x`

into which we put`y`

. Note that the array is not circular -- if we reach the end without finding an empty slot, we give up. - If there is no empty slot after
`x`

at all, we resize the array. This means we make a new array twice as big as the number of elements we are storing, and copy all the*real*entries of the old array, in order, into the even-numbered entries of the new one. Thus the new array is exactly half full -- it is*not*necessarily twice the size of the old array. We then insert`y`

into the new empty slot immediately after`x`

.### Exercises:

**Question 1:**Trace the following code given the description of the`HoleyList`

class above. Remember that these entries are`String`

objects, not`Dog`

objects, and that the natural order on`String`

objects is just ordinary dictionary order. Describe the entire array after each operation.`String [ ] someDogs = {"Ace", "Biscuit", "Cardie"}; HoleyList<String> holey = new HoleyList<String>(someDogs); holey.add ("Balto"); holey.add ("Buck"); holey.add ("Bella"); holey.remove ("Ace"); holey.add ("Duncan"); holey.add ("Abigail"); holey.add ("Aaron");`

**Question 2:**Write a constructor`public HoleyList (T [ ] input)`

for`HoleyList`

. You may (or may not) find it convenient to write a method`copyToEvens (T [ ] oldArray, T [ ] newArray)`

that you can also use later. For the constructor, you may assume that the input array is in the natural order and contains no empty slots.**Question 3:**Write the`add`

and`remove`

methods for`HoleyList`

. You may find it convenient to write a`find`

method first. Remember that`remove`

takes a`T`

parameter. It throws an`EmptyCollectionException`

if the list is empty, and an`ElementNotFoundException`

if the parameter is not equal to any element in the list.**Question 4:**In our array implementations of stacks, queues, and deques, the`add`

operation "took O(1) time, except for resizing." But the`add`

operation of an`ArrayList`

, in either L&C's version or the library version, takes O(n) time in the worst case even without resizing. Is the`add`

operation of our new class "O(1) in the worst case, except for resizing"? Justify your answer.Last modified 27 October 2011