5 Array-Based Structures

Version 4.31

Handouts:

Read Chapter 5, "Array-Based Structures." Principal points to understand:

  1. How array-based structures can be made to vary in size (shrink and stretch).
  2. How array-based structures can implement stacks and queues.
  3. The List interface and its array-based implementation.
  4. What are Iterators, and how are they implemented.
  5. How are the interfaces and classes of the Java Collections Framework related to those presented in this text?

Part A: Pages 119–139

Most abstract data types (ADTs) have at least two implementations, one using arrays and one using linked structures. This week, we look at the array-based implementations of some ADTs that we have previously studied, as well as some new ADTs.

5.1 Shrinking and Stretching Arrays

Arrays are fixed-length objects: once an array is allocated, its size (length, number of elements) cannot be changed. (Note: this does not mean that array-type variables cannot store references to various different sizes of array of the same type. The length of an array is not part of its data type.)

Working around this, we can still "shrink" and "expand" arrays in a certain sense.

The Card and Deck classes, pp. 120 ff.

Expanding arrays, the basic idea: create a new, larger array and copy the contents of the old array into it. Details in the next section.

Discuss exercises, p. 126: #5.1–5.4.

5.2 Implementing Stacks and Queues

The ArrayStack Class, pp. 127–129

Basic diagram: a stack containing elements (bottom to top) w, x, y, z:

PNG image of an array-based stack

PNG image of an array-based stack

The size field is the index of what will become the new top if a push is performed. The actual top of stack, if any, is at data[size - 1] .

Sketch what happens as we push and pop elements.

Discuss code; walk through a few examples.

The ArrayQueue Class

Basic diagram: a queue containing A (at the front), B, C, D:

PNG image of an array-based queue

PNG image of an array-based queue

The front element, if the queue is non-empty, is data[front] .

Preliminary statement: The rear element, if the queue is non-empty, is at data[front + size - 1] ; front + size is the index of what will become the new rear if another element is enqueued. (This is a preliminary statement of where the rear is, which we will qualify below.)

Sketch what happens as we enqueue and dequeue elements.

What happens as more and more elements are dequeued, so that front approaches the highest array subscript?

PNG image of an array-based queue

PNG image of an array-based queue

What are the elements, from front to rear?

Now we qualify the preliminary statement about the location of the rear of the queue:

The rear element, if the queue is non-empty, is at data[(front + size - 1) % N] , where N is the array length of data; the next element enqueued goes in at data[(front + size) % N] . (In the sketches above, N = 10, which would not happen in the implementation because N would always be a power of 2l.) So we might think of "rear" as a virtual field = (front + size) % N and indicating the point for insertion of the next element.

Discuss code.

Discuss exercises: p. 133, # 5.7, 5.8 (?), 5.9–5.12.

5.3 The List Interface

A List is a sequence of elements which allows access at both ends and at all positions in between. Thus, it is more general than Stack and Queue, which allow access only at one or both ends.

The List Interface, p. 134

Note: the term 'list' is more flexible in its meaning than the terms 'stack' and 'queue'. Stack and queue have a well-defined, universally understood set of operations. Lists, on the other hand—there are many possible variations in what one can mean by list, and what a list can do. For example:

The ArrayList Class, pp. 135–137

PNG image of an array-based list

PNG image of an array-based list

Discuss exercises: pp. 138–139, #5.16, 5.17, 5.19–5.22.

Part B: Pages 139–154

5.4 Iterators

What Is an Iterator

Interfaces

Some Classes Implementing Iterator

An Application

The game of Go Fish.

Disputation

(1) I'm not convinced that Iterators are so useful here, or in general. Can we try rewriting the give or meldSets method of GoFishHand without using Iterators?

Pseudocode for replacing the iterator loop in give:

i = 0
while i < size:
  card = get(i)
  if card's rank == rank:
    remove(i)
    add card to taker hand
    foundAny = true
  else:
    i++

That doesn't seem more complicated than with the iterator, does it?

If we counted downwards from size−1 to 0, it would be even simpler:

for i = size - 1 down to 0:
  card = get(i)
  if card's rank == rank:
    remove(i)
    add card to taker hand
    foundAny = true

In other words, we can easily do it directly, without the iterator. So why use an iterator?

(2) In general, what we can do with iterators is fairly limited: with each element, we get to observe it (next() method), and we get to delete it (remove() method). What if we wanted to replace it with a different element, or duplicate it, or add a new element?

(3) It seems that the real usefulness of iterators is when we want people to be able to traverse a collection without knowing the collection's structure. That is, we let them observe (next()) and remove() each element, one after another, in some order, but without implying that the elements are really ordered that way in the collection. That is, we treat the collection in a somewhat abstract way as a collection, rather than a sequence.

What I'm saying here probably doesn't make a whole lot of sense when the only iterable collections we've seen are lists. But there are also trees and hash tables, for example.

Okay, sketch a tree and explain what this means.

Iterator exercises

(Maybe discuss) page 150–151: #5.24, 5.25, maybe 5.26 and 5.27

5.5 The Java Collections Framework

Abstract Classes

Exercises and Problems

(Possibly)

Footnotes


  1. Revision history:
    • Version 4.3, 2010 Sep 27. Added Scanner as an example of Iterator.
    • Version 4.2, 2010 Sep 21. Converted to markdown, removed old diagrams.
    • Version 4.1, 2009 Nov 27. Added new diagrams made with structview. I should remove the old diagrams when I'm completely happy with the style of the new.
    • Version 4, 2008 Sep 21, converted to reStructuredText
    • Version 3, 2007 Sep 14, added diagram of array list.
    • Version 2, 2007 Sep 14.
    • Version 1, 2006 Sep 21.