More on Arrays

Example:

String[] words = new String[8];

words[0] = words[0].trim();

What happens when we run this code?

Null
Pointer Mistake

Question: How can we fix the problem in our last example?

Answer: Initialize the array entries

String[] words = new String[8];

for(int i = 0; i < words.length; i++)

{

words[i] = " String " + (i+1);

}

words[0] = words[0].trim(); // no problem now

Searching Arrays for a Value

Searching - locating a particular value (the key) in an array

First Search Algorithm: Linear Search

(Also known as Sequential Search)

- works well for small arrays or unsorted arrays (a sorted array is an array whose entries are in increasing or decreasing order)
- looks at each array entry, starting with first, until either:
- search key is found (and it's index is returned)
- end of array reached (negative integer, say -1, returned)

Code for linear search, for an int array:

public int linearSearch(int[] array, int key)

{

//return key's index in array, or -1 if key does not appear

for(int i = 0; i < array.length; i++)

{

if(array[i] == key) return i;

}

return -1;

}

Algorithm
Analysis for Linear Search

If the array elements are unsorted, on average the linear search algorithm will compare the key to half the array elements.

For an array of size n: n/2 comparisons in average case.

How many comparisons in the best case? Worst case?

Second Search Algorithm: Binary Search

- requires a sorted array - algorithm fails on unsorted arrays
- eliminates half of remaining array entries from consideration after each comparison
- compares the middle of the remaining array elements to search key on each pass
- if they are equal, return index
- if not, and search key < middle array element, search first half of array
- else search second half of array

Example: Search for key = 40 in array containing:

2, 5, 7, 10, 15, 31, 40, 55

Code for Binary Search:

public int binarySearch(int[] array, int key)

{

int low = 0;

int high = array.length - 1;

while(low <= high) // search elts in pos low to high

{

int mid = (low + high)/2; // middle pos in search range

if(array[mid] == key)

return mid;

else if(array[mid] < key) // search top half

low = mid+1;

else // search bottom half

high = mid-1;

}

return -1;

}

Algorithm Analysis for Binary Search

Example: In an array of 64 elements, binary search eliminates half the array from consideration after each comparison. Repeatedly dividing by 2, we get:

32 elements after 1 comparison

16 elements after 2 comparisons

8 elements after 3 comparisons

4 elements after 4 comparisons

2 elements after 5 comparisons

1 element after 6 comparisons (note that 2^6 = 64)

So 6 comparisons are needed to search an array of 64 elts.

Note: Linear Search on average would do 64/2 = 32 comparisons.

Binary Search: n comparisons to search array of size 2^n.

Java's
Arrays Class

- class in java.util package
- static methods that perform operations on arrays

Method
Name |
How
it Works |

binarySearch(array,
key) |
returns
index of key in array, or -1 if array does not contain key |

fill(array, value) |
fills the entries
in the array with value |

sort(array) |
rearranges the
array entries into increasing order |

equals(array1,
array2) |
returns true if
the arrays contain the same entries in the same order |

toString(array) |
returns a String
representation of the array |

Using the Arrays class Methods

Example:

int[] nums = {-45, 3, 21, 84, 101, 147};

int pos = Arrays.binarySearch(nums, 84);

System.out.println("Position of 84: " + pos);

Output: Position of 84: 3

Example:

int[] nums = {2, 16, -4, 12, 101, 25};

Arrays.sort(nums);

int pos = Arrays.binarySearch(nums, -4);

System.out.println("Pos of -4: " + pos);

System.out.println(Arrays.toString(nums));

Output:

Pos of -4: 0

[-4, 2, 12, 16, 25, 101]

Example: Write a method that takes a sorted array of ints, and an int, and inserts the int into the array in the correct position. The last array entry is lost.

That is, if the array is {-1, 4, 17, 85, 100} and the value is 2,

then the array becomes {-1, 2, 4, 17, 85} after the method is called.

Exercise: Write a method called equal that takes two arrays of ints as arguments, and returns true if the arrays contain the same elements in the same order, and false otherwise.

Two-Dimensional
Arrays

- used to represent tables with rows and columns
- 2 index values - first is row number, second is column number
- Indexing still starts at 0
- arrayName[i][j] is the entry at row i, col j
- If the array is a number type, the entries are set to 0 when the array is created. If the array is a reference type, the entries are are set to null when the array is created.
- An array of arrays - so the length of the
array is the number of rows.

Declaring a 2-dimensional array:

int[][] myArr = new int[3][4]; // array of 3 rows, 4 cols

Initializing an Entry:

a[0][0] = 5;

a[0][1] = 17;

Example: Initializing all array entries to 1

int[][] myArr = new int[10][10]; //all entries are 0

for(int i = 0; i < myArr.length; i++)

{

// the number of elements in row i is myArr[i].length

for(int j = 0; j < myArr[i].length; j++)

{

a[i][j] = 1;

}

}

Using an Initialization List

We can specify the elements in each row with an initialization list:

int[][] myArr = {{1, 2}, {3, 4}};

- the first row contains 1 and 2, the second row contains 3 and 4
- the compiler determines the number of rows by
counting the number of sub-initializer lists in the main initializer
list.

- the number of columns in a row is the number of values in the corresponding sub-initializer list.
- Different rows may have a different numbers of entries ("ragged array")
- double[][] fpArray = {{1, 2, 3}, {4, 5}, {6}};
- 1st row - 3 entries
- 2nd row - 2 entries
- 3rd row - 1 entry

Multi-Dimensional
Array Examples

Example: Write a method that takes a 2-dim array of floating-point numbers, and returns the sum of all the entries in the array.

Example: Write a method that takes a 2-dim array of floating-point numbers and an int index, and returns the sum of the row with the specified index. If the index is not valid, return 0.

Example: Write a method that takes a square matrix (ie, an array with the same number of rows and cols) of ints, and returns the sum of the diagonal entries.

Example: Write a method that takes two arrays with the same dimensions, and adds them - it returns an array that contains the sum. In position i, j, the new array contains the sum of the entries in position i, j in the two arguments.

Sorting

Problem: Given an array A[N] (ie, a one-dim array of N entries), arrange A's elements in ascending order.

2 basic operations in sorting algorithms:

- swap - exchange the position of 2 entries in the array
- pairwise comparison - determine which of 2 entries is largest

Note: What we mean by "largest" depends on the application-

- If the array contains Strings, "largest" could refer to dictionary order.
- If the array contains student records - e.g.,
objects of type Student - "largest" could mean the record containing
the highest GPA, or student whose name comes last in alphabetical order.

Choosing a Sorting Algorithm

There are a number of different sorting algorithms - how do you choose the right one for your application?

Answer: To make a good choice, you must consider the number of swaps and the number of comparisons (to an array entry) each algorithm does.

- Sometimes comparisons are costly, e.g., it takes longer to compare 2 Strings than 2 ints
- Sometimes you may be willing to do more swaps to minimize the number of comparisons, but think about the time required for each operation.

Selection Sort

To sort A's entries into increasing order:

Step 0: Find smallest entry in A[0..N-1] and swap it with A[0].

Step 1: Find smallest entry in A[1..N-1] and swap it with A[1].

...

Step i: Find smallest entry in A[i..N-1] and swap it with A[i].

Solution grows from low end of the array. After step i, A[0], A[1], ..., A[i] contain the

correct values.

Example: Use selection sort to sort an array containing the values 3 1 10 7 2

Selection Sort Algorithm and Code

for i = 0 to N-2

find min of A[i], A[i+1], ..., A[N-1]. Call min A[minIndex].

Swap A[i] and A[minIndex].

public void selectionSort(double[] A)

{

for(int i = 0; i < A.length-1; i++)

{

// find the value that belongs in position i

minIndex = i;

for(int j = i+1; j < A.length; j++)

{

if(A[j] < A[minIndex]) minIndex = j;

}

// swap A[i] and A[minIndex]

double temp = A[i];

A[i] = A[minIndex];

A[minIndex] = temp;

}

}

Analysis of Selection Sort

Note: Order of data does not affect number of swaps or comparisons done.

# of swaps: (in class)

# of comparisons: (in class)

There are faster sorting algorithms, but selection sort doesn't do a lot of swaps.

Insertion Sort

- Works the way many people sort a hand of playing cards
- Pick up 1 item at a time and put it in place among already sorted items

Step 1: The subarray A[0..0] is already sorted.

If A[1] is not in place in A[0..1], swap A[1] with A[0].

Now A[0..1] is sorted.

Step 2: The subarray A[0..1] is already sorted.

If current = A[2] is not in place in A[0..2], swap it with A[1].

If current is not in place in A[0..2], swap it with A[0].

Now A[0..2] is sorted.

...

Step i: Subarray A[0..i-1] is sorted.

If current = A[i] is not in place in A[0..i], swap current successively

with A[i-1], A[i-2], ... until current is in its correct place in A[0..i].

Now A[0..i] is sorted.

Example: 3 J 10 7 2

Psuedo-code:

For i = 0 to N-1

For(j = i; j > 0 && A[j] < A[j-1]; j--)

swap A[j] and A[j-1]

Example: Array containing 10 9 5 6