University of Aberdeen Home Page Department of Computing Science Home Page
CSD Level Two Home Page
CS2005 Home CS2005 Lectures CS2005 Practicals CS2005 Tutorials CS2005 Information

Week 3 Lectures - The Array Data Structure

Aims

  • Define the Array data structure
  • Illustrate implementation of arrays in Java
  • Consider elementary array algorithms
  • Describe and illustrate the java.lang Comparable interface
  • Explain the Merge & Merge Sort algorithms

Learning Outcomes

By the end of week 4 of teaching you should be able to:

  • define simple array algorithms;
  • determine the efficiency and complexity of simple array algorithms;
  • understand and use the java.lang.Comparable interface;
  • implement a sorting algorithm in Java;
  • recall the main points of Watt & Brown chapter 3.

Reference: Watt & Brown chapter 3.

The Array

  • An indexed sequence of components or elements
  • The indices are sequential, with upper and lower bounds
  • The index provides direct access to the corresponding component

Java Arrays

  • Indices range from 0 to length-1
  • Each component of the same type
  • Syntax a[i] and a.length
  • Allocated dynamically (using new) and accessed by reference
  • Length fixed when storage is allocated

Example

Simple Integer Array I/O

Basic Array Algorithms

Insert Component

Insert val at position ins in a[left..right]
This is an O(n) algorithm.
Note: in Java quite often left will be zero and right will be a.length-1, however this algorithm is described for the more general situation when left..right is any subrange of 0..a.length-1. The same comment applies to subsequent algorithms.

1. Check left <= ins <= right
2. Copy a[ins..right-1] into a[ins+1..right]
3. Copy val into a[ins]

Note that the original value a[right] is lost. If there are unoccupied positions at the end of the array then we would choose right to be one more than the last occupied position to ensure that no information is lost.

Note also that the order of performing the copy operations in step 2 is important.

Delete Component

Delete the value at position del in a[left..right]
This is an O(n) algorithm.

1. Check left <= del <= right
2. Copy a[del+1..right] into a[del..right-1]
3. Make a[right] unoccupied

Note that to ensure that no vital information is lost we would choose right to be the rightmost occupied position in the array (this might not necessarily be position a.length-1.

Note also that the order of performing the copy operations in step 2 is important.

Linear Search

Search for target in a[left..right]
This is an O(n) algorithm.

1. Loop using p = left..right
	1.1 If a[p] equals target then return index p
2. Return a value indicating target not found

Note that there is no 'correct' way to show that the target is not found. Sometimes an index value of -1 is used.

Sorted Arrays

In a sorted array a[left..right] the components satisfy

a[i] is 'less than or equal to' a[i+1] for i = left..right-1

The meaning of 'less than or equal to' will be determined by the type of component. An array can be inverse-sorted in a similar way.

Java provides comparison operators for comparing primitive types such as char, integer or float. For reference types methods have to be written to perform comparisons. Java 2 provides a java.lang.Comparable interface that requires a CompareTo method to compare two objects. Some Java 2 library classes (including Integer and String) implement java.lang.Comparable.

Linear Search - Sorted Array

Search for target in a[left..right]
This is an O(n) algorithm.

1. Loop using p = left..right
	1.1 If a[p] greater than or equal to target then exit the loop
2. If a[p] equals target then
	2.1 return index p
3. Else
	3.1 return value indicating 'not found'

Note that we will exit, on average, half way through the traversal between a[left] and a[right].

Binary Search (recursive)

See Watt & Brown 3.4.2 for a non-recursive version

Search(target,a,left,right)
- search for target in a[left..right]
This is an O(log n) algorithm.

1. If left >= right then
	1.1 If a[left] equals target then
		1.1.1 return index left
	1.2 Else
		1.2.1 return -1 (i.e. 'not found')
2. Set mid = (left+right)/2
3. If target is greater than a[mid] then
	3.1 return Search(target,a,mid+1,right)
4. Else
	4.1 return Search(target,a,left,mid)

Note that we could include a test for target = a[mid] at step 3, but this would double the number of tests overall without significantly reducing the depth of recursion.

Sorting Example

The InsertionSort program makes use of the non-recursive Binary Search algorithm. See also the html file produced by javadoc. You will see from this html document that the InsertionSort program makes use of two other classes for reading from and writing to a text file. These classes are TextReader and TextWriter They are available for you to download and use if you wish. Note that on these pages they are stored as ".txt" files, so that the browser will display them. If you download them then you should save them in the directory that contains the Java class that will use them, and you should save them as ".java" files.

Comparing Objects in Java

Java types char, int, short, long, float and double can all be compared using the logical comparison operators (e.g. < and ==). However, more generally Java objects have to use methods to perform comparisons - the comparison operators either will not work, or will give a misleading result. For example, if variables S1 and S2 are type String, then the test
(S1 == S2)
will determine whether S1 and S2 are stored in the same place in memory, and not whether S1 and S2 contain the same string data value.

All objects have an equals method to facilitate testing one object with another. E.g. to test two strings for equality we use the code
S1.equals(S2)
By default this equals method carries out exactly the same shallow test as the == operator. However, when defining an object the default equals can (and usually should) be over-ridden with a new method that performs a deeper comparison of actual data values. Type String does this, as can be seen from the java/lang/String specification.

The Java String type can also make use of a compareTo method, as in
int i = S1.compareTo(S2);
The result i is negative if S1<S2, zero if S1==S2, and positive if S1>S2.

This compareTo method is an implementation of the java.lang.Comparable interface. Any object can be defined to implement this interface. Of particular interest are the java.lang.Integer , java.lang.Double , etc classes, which are object types that are 'wrappers' for the simple Java types int, double, etc.

The Merge Algorithm

See Watt & Brown 3.5 for the algorithm. Here is a sample Java method, which uses compareTo when comparing objects. Note the use of the Comparable class, which ensures that the Merge method will work for arrays of any Java object that implements the Comparable interface.

Merge Sort

The Merge Algorithm can be used to complete a complete sort of a range of values in an array.

The Merge Sort algorithm can be described recursively as follows.

Sort(a,left,right)

  1. If left >= right return (sorted already)
  2. Set mid = midpoint between left and right
  3. Sort(a,left,mid) and Sort(a,mid+1,right)
  4. Merge(a,left,mid,a,mid+1,right,b,left)
  5. Copy b[left..right] into a[left..right]
  6. Return

The array b should be declared outside the Sort method. If it is declared (or instantiated using "new") within the Sort method then there will be significant memory overheads caused by recursion. If declared outside the sort method it can be safely passed to the sort method as a parameter.

 

You can obtain a text only version of this page by following the link.

CS2005 | Lectures | Practicals | Tutorials | Information

University of Aberdeen