Let’s examine some Java code that implements an ordered array. We’ll use the OrdArray class to
encapsulate the array and its algorithms. The heart of this class is the find() method, which uses a binary search to locate a specified data item. We’ll examine this method in detail before showing the complete program.
BINARY SEARCH WITH THE find() METHOD
The find() method searches for a specified item by repeatedly dividing in half the range of array elements to be considered. Here’s how this method looks:
public int find(double searchKey) {
int lowerBound = 0;
int upperBound = nElems−1; int curIn;
while(true) {
curIn = (lowerBound + upperBound ) / 2; if(a[curIn]==searchKey)
return curIn; // found it else if(lowerBound > upperBound)
return nElems; // can’t find it else // divide range {
if(a[curIn] < searchKey)
lowerBound = curIn + 1; // it’s in upper half else
upperBound = curIn − 1; // it’s in lower half } // end else divide range
} // end while } // end find()
The method begins by setting the lowerBound and upperBound variables to the first and last occupied cells in the array. This specifies the range where the item we’re looking for, searchKey, may be found. Then, within the while loop, the current index, curIn, is set to the middle of this range.
If we’re lucky, curIn may already be pointing to the desired item, so we first check if this is true. If it is, we’ve found the item so we return with its index, curIn.
Each time through the loop we divide the range in half. Eventually it will get so small it can’t be divided any more. We check for this in the next statement: If lowerBound is greater than upperBound, the range has ceased to exist. (When lowerBound equals upperBound the range is one and we need one more pass through the loop.) We can’t continue the search without a valid range, but we haven’t found the desired item, so we return nElems, the total number of items. This isn’t a valid index, because the last filled cell in the array is nElems−1. The class user interprets this value to mean that the item wasn’t found.
If curIn is not pointing at the desired item, and the range is still big enough, then we’re ready to divide the range in half. We compare the value at the current index, a[curIn], which is in the middle of the range, with the value to be found, searchKey.
If searchKey is larger, then we know we should look in the upper half of the range. Accordingly, we move
lowerBound up to curIn.
Actually we move it one cell beyond curIn, because we’ve already checked curIn itself at the beginning of the loop.
If searchKey is smaller than a[curIn], we know we should look in the lower half of the range. So we move upperBound down to one cell below curIn. Figure 2.8 shows how the range is altered in these two situations.
FIGURE 2.8 Dividing the range in a binary search
Previous Table of Contents Next
MWSS: Data Structures and Algorithms in Java
by Robert Lafore
Waite Group Press, Macmillan Computer Publishing ISBN: 1571690956 Pub Date: 03/20/98
Previous Table of Contents Next
THE OrdArray CLASS
In general, the orderedArray.java program is similar to highArray.java. The main difference is that find() uses a binary search, as we’ve seen.
We could have used a binary search to locate the position where a new item will be inserted. This involves a variation on the find() routine, but for simplicity we retain the linear search in insert(). The speed penalty may not be important because, as we’ve seen, an average of half the items must be moved anyway when an insertion is performed, so insertion will not be very fast even if we locate the item with a binary search. However, for the last ounce of speed, you could change the initial part of insert() to a binary search (as is done in the Ordered Workshop applet). Similarly, the delete() method could call find() to figure out the location of the item to be deleted.
The OrdArray class includes a new size() method, which returns the number of data items currently in the array. This is helpful for the class user, main(), when it calls find(). If find() returns nElems, which main() can discover with size(), then the search was unsuccessful. Listing 2.4 shows the complete listing for the orderedArray.java program.
Listing 2.4 The orderedArray.java Program
// orderedArray.java
// demonstrates ordered array class // to run this program: C>java OrderedApp import java.io.*; // for I/O
//////////////////////////////////////////////////////////////// class OrdArray
{
private double[] a; // ref to array a private int nElems; // number of data items //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− public OrdArray(int max) // constructor
{
a = new double[max]; // create array nElems = 0;
}
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− public int size()
{ return nElems; }
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− public int find(double searchKey)
{
int lowerBound = 0;
int upperBound = nElems−1; int curIn;
while(true) {
curIn = (lowerBound + upperBound ) / 2; if(a[curIn]==searchKey)
return curIn; // found it else if(lowerBound > upperBound)
return nElems; // can’t find it
else // divide range {
if(a[curIn] < searchKey)
lowerBound = curIn + 1; // it’s in upper half else
upperBound = curIn − 1; // it’s in lower half } // end else divide range
} // end while } // end find()
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− public void insert(double value) // put element into array {
int j;
for(j=0; j<nElems; j++) // find where it goes if(a[j] > value) // (linear search) break;
for(int k=nElems; k>j; k−−) // move higher ones up a[k] = a[k−1];
a[j] = value; // insert it nElems++; // increment size } // end insert()
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− public boolean delete(double value)
{
int j = find(value);
if(j==nElems) // can’t find it return false;
else // found it {
for(int k=j; k<nElems; k++) // move higher ones down a[k] = a[k+1];
nElems−−; // decrement size return true;
}
} // end delete()
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− public void display() // displays array contents {
for(int j=0; j<nElems; j++) // for each element, System.out.print(a[j] + “ “); // display it
System.out.println(“”); }
//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− } // end class OrdArray
//////////////////////////////////////////////////////////////// class OrderedApp
{
public static void main(String[] args) {
int maxSize = 100; // array size
OrdArray arr; // reference to array arr = new OrdArray(maxSize); // create the array
arr.insert(77); // insert 10 items arr.insert(99); arr.insert(44); arr.insert(55); arr.insert(22); arr.insert(88); arr.insert(11); arr.insert(00); arr.insert(66); arr.insert(33);
int searchKey = 55; // search for item if( arr.find(searchKey) != arr.size() )
System.out.println(“Found “ + searchKey);
else
System.out.println(“Can’t find “ + searchKey);
arr.display(); // display items
arr.delete(00); // delete 3 items arr.delete(55);
arr.delete(99);
arr.display(); // display items again } // end main()
} // end class OrderedApp
ADVANTAGES OF ORDERED ARRAYS
What have we gained by using an ordered array? The major advantage is that search times are much faster than in an unordered array. The disadvantage is that insertion takes longer, because all the data items with a higher key value must be moved up to make room. Deletions are slow in both ordered and unordered arrays, because items must be moved down to fill the hole left by the deleted item.
Ordered arrays are therefore useful in situations in which searches are frequent, but insertions and deletions are not. An ordered array might be appropriate for a database of company employees, for example. Hiring new employees and laying off existing ones would probably be infrequent occurrences compared with accessing an existing employee’s record for information or updating it to reflect changes in salary, address, and so on.
A retail store inventory, on the other hand, would not be a good candidate for an ordered array because the frequent insertions and deletions, as items arrived in the store and were sold, would run slowly.
Previous Table of Contents Next
MWSS: Data Structures and Algorithms in Java
by Robert Lafore
Waite Group Press, Macmillan Computer Publishing ISBN: 1571690956 Pub Date: 03/20/98
Previous Table of Contents Next