Concepts / Returning Values from Methods

Returning Values from Methods

A linear search checks each item of an array in turn. It finishes as soon as it finds the item, and it can conclude the item is absent only after checking every position.

  • Programming

Why Start With the Simplest Search

Suppose you have an array of integers and you need to know whether a particular value appears in it, and if so, where. The array gives you no hints about where the value might be. It is not sorted, and nothing else tells you which position to try first. What is the most direct method you could use?

The most direct method is also the most obvious one: look at each item in the array in turn, and check whether that item is the one you are looking for. If you find it, the search is finished. If you look at every item without finding the one you want, you can be sure the item is not in the array. This method is called a linear search. In this article you will start from code that performs the search, predict its result before running it, and then trace the mechanism that produces that result.

Reading the find Method

The following Java method searches an array of ints for a specified integer. It takes the array A and the integer N to look for. Read it once for its overall shape before you worry about individual lines. Notice that the declared return type is int, so the method hands back a single integer to whoever calls it.

java
Notes on the code
  • The return type int tells the caller that exactly one integer comes back
  • The parameters A and N are the array to search and the value to look for
  • The loop variable index is the only thing that moves through the array
  • return index exits the method on the first match
  • return -1 is reached only when the loop finishes without a match

Two return statements appear in this method, and they play different roles. The one inside the if block is reached only when a match has been found. The one after the loop is reached only when every position has been checked and none matched. Which of these two statements the method executes determines what the caller receives, so the rest of this article follows that choice.

Predicting Before You Run

Before you move on, make a prediction. Consider the array {4, 8, 8, 2} and a call to find with N equal to 8. The value 8 appears twice, at positions 1 and 2. Decide which index you expect find to return, and state the reason from the loop itself rather than from guessing.

What do you think happens?

For the array {4, 8, 8, 2}, what index does find(A, 8) return?

  • 0

  • 1

  • 2

  • 3

  • -1

Reveal answer
Answer:

1

The loop starts at index 0, where the element 4 does not equal 8, so nothing is recorded and the loop continues. At index 1 the element 8 equals N, so the method returns 1 immediately. The second 8 at index 2 is never examined, because the method has already left the loop.

Tracing the Loop Position by Position

The loop variable index is the only thing that moves through the array. It begins at 0 and increases by one each time the loop body finishes, stopping once index reaches the length of the array. On each pass the method asks a single question: does the element at this position equal N? If the answer is no, nothing is recorded and the loop moves on. If the answer is yes, the method leaves immediately and reports the position.

index 04 is not 8, continueindex 18 equals 8, stopreturn 1index 2never reachedindex increases by onematch foundwould continue only without a match
After each comparison, which index is being checked next, and at what point does the loop stop: on a match or after the last position?

The diagram shows that the loop never looks ahead. The value at index 2 is an 8 as well, but the method never gets there. This is the first consequence of the design: the search stops at the first position that satisfies the comparison.

Mapping Positions to the Returned Index

The method has no memory of earlier mismatches. It does not count them or keep a list of places it has checked. Each position is judged alone, and the answer is determined by the first position that satisfies the comparison. Because of this, when several positions hold the same value, the index returned is always the smallest of them.

position 04position 18position 28position 32
Which array element sits at each index, and which index is returned when the target value is found at a given position?

In the diagram, position 1 is highlighted because it is the one the search returns. Position 2 also holds an 8, yet it is never the result. If you changed the array to {4, 8, 8, 2} and asked for the 8 again, you would still get 1, not 2, because index 1 is the smallest position holding that value.

Two Ways the Search Can Stop

The method can finish in exactly two ways. One is through a match, which returns an index. The other is through exhausting the array, which returns -1. The flowchart below shows the same decisions as the method, in the order control moves between them.

start at index 0index less thanlength?A[index] equals N?increase indexreturn indexmatch foundreturn -1every position checkedyesnoyesnorepeat
Which branch causes the method to return immediately, and which condition is only reached after every position has been checked without a match?

The branch that returns an index is taken as soon as a match appears, so it can exit the loop while many positions remain unchecked. The branch that returns -1 can only be reached after the loop condition fails, which means every position has been examined without success. This asymmetry is what lets the method conclude absence safely: it cannot claim the value is missing until it has looked everywhere.

Index Versus -1 for the Caller

A caller receives a single int, and that int must carry two different meanings: either the position where the value was found, or a signal that it was not found. The method relies on -1 for the second meaning. This choice is safe because -1 is never a valid index, so no real position can be confused with the not-found signal.

Returned valueWhat it meansWhere it comes fromWhat the caller should do
A value 0 or greaterThe value was found at this index, and this is the smallest index holding itreturn index inside the loopUse the index to read or locate the element
-1The value is not in the arrayreturn -1 after the loop finishesTreat the value as absent, and do not use it as an index

Interpreting the two possible return values of find

java
Output
1
-1
Notes on the code
  • find(A, 8) returns 1, the smallest index holding 8
  • find(A, 5) returns -1, because 5 never appears in the array

Mistakes Beginners Make

  • Common mistake

    Expecting the last matching position to be returned

    What it looks like

    For {4, 8, 8, 2} and N = 8, expecting find to return 2.

    Why it fails

    The loop exits at the first position where the comparison succeeds, so the later 8 at index 2 is never examined.

    Do this instead

    Expect the smallest matching index, which here is 1.

  • Common mistake

    Treating -1 as a position in the array

    What it looks like

    Writing A[find(A, 5)] without checking the result first.

    Why it fails

    -1 is the not-found signal, and it is never a valid index, so reading that position fails.

    Do this instead

    Check whether the result is -1 before using it as an index.

  • Common mistake

    Concluding absence before the loop has finished

    What it looks like

    Assuming 5 is missing after checking only the first two positions.

    Why it fails

    The method reports -1 only after every position has been checked without a match.

    Do this instead

    Let the loop run to the end of the array before accepting that the value is absent.

  • Common mistake

    Assuming the method remembers earlier mismatches, when each position is judged alone

Practice: Trace a Search

EASY

Given the array {7, 3, 9, 3, 5} and the call find(A, 3), state the value returned before you check it. Then list each index the loop visits, and say at which index the loop stops and why.

Hints
  • Start at index 0 and compare A[index] with N on each pass.
  • Ask at which index the first equal element appears, not the last one.
  • A call with a value that never appears would instead end with -1 after the loop finishes.

Key Takeaways

  • A linear search checks each position of an array in turn, starting at index 0, and stops as soon as the sought value is found.
  • The method can conclude that a value is absent only after every position has been checked without a match, which is why it returns -1 only after the loop ends.
  • When several positions hold the same value, find returns the smallest of those indices, because the first match ends the search.
  • The return value -1 is a safe not-found signal because it is never a valid index, so callers must check for it before using the result as a position.
  • When a result surprises you, find the first iteration where the behavior departed from your prediction, since that point usually reveals the fault.