Let us first explore why arrays are useful. This can be illustrated using an example.
The code that we need to find the maximum of two variables and is simple. It is represented in algorithm 1.
If we add one more variable, , then the algorithm gets more complicated, as described in algorithm 2.
What if we have given 20 values? 200 values? 2000 values?
As you can see, this approach does not “scale”. In other words, the algorithm becomes more and more complicated as the number of values increases. However, if we use an array of numbers, then the algorithm is much simple, as described in algorithm 3.
Of course, the complexity of algorithm 3 doesn’t appear to be much simpler than algorithm 2. However, algorithm 3 works for 3 values, 30, values, 3000 values, and etc. The same algorithm works for any number of values!
An array can be seen as one variable. However, it is actually the composite of many elements. An array has several attributes:
Note that each element of an array can behave like a variable on its own. You can use it on either side of an assignment, you can perform mathematical operations, you can compare and etc.
Let us consider an algorithm that initializes an array so that all elements become 0. This algorithm is illustrated in algorithm 4.
Let us analyze each line of code here.
When we trace an algorithm involving an array, each element in the array has its own column. This is hardly surprising because each element in an array is an independent variable! This fact does make the trace of an algorithm involving an array rather tedious. A table/spreadsheet should be used because the gridlines help significantly.
As an exercise, trace algorithm 4, assuming array has 3 elements.
Given an unsorted array and a value to find, how do we know whether the array has an element that matches the value or not?
Algorithm 5 is the not-so-formal version.
Recall our technique of using an integer variable to control which element we want to access. We an reapply that technique here. In fact, we’ll use the same variable for this purpose.
To start with the first element means should be initialized to 0. Hence, we have as our first statement.
Next, let us consider the phrase “there are more elements.” Since we start with the first element, then as long as the index remains within the range of 0 to , there is at least one more element to consider. Consequently, “there are more elements” translates to the condition . Note that we cannot use because when , is not defined anymore.
The next phrase to consider is “the current one does not match ”. The “current one” is an element controled by the indexing variable . In other words, the “current one” is simply . To say that does not match is to say .
As a result, the condition of the prechecking loop can be more formally written as .
The only thing to do in the loop is to move on the next element. Because the current element is controled by the indexing variable , to move on to the next element is to bump up by 1. This means the action “move on to the next element” is really just .
In the conditional (if-then-else) statement, how do we know we have exhausted all the elements in the array? If we have searched through the array and no element matches, , and that is the reason to exit the prechecking loop. As a result, “we have exhausted all elements” should be replaced by .
Algorithm 6 is the result of replacing all the not-so-formal description with formal pseudocode.
Again, it really helps to trace an algorithm. In this case, try to consider as an array of 4 elements. Let’s assume , , and .
Perform two traces. First, assume , trace. Then, assume , trace.