SDD13 — Standard Algorithms: Linear Search
- I can explain how the linear search algorithm works
- I can write a linear search in Python that returns the index of a target value, or a sentinel value if it is not found
- I can trace a linear search by hand, recording each comparison made
- I can describe linear search as checking each element of an array in order, from the start, until the target is found or the array ends
- I can implement linear search using a loop and a Boolean "found" flag
- I can explain why a sentinel value such as
-1is used to signal "not found" - I can complete a trace table showing the index and comparison made at each step of a search
+ to other text?file.write("A") then file.write("B"), with no newline characters. What does the file contain?Key vocabulary
-1) returned to signal that the target was not found, since no valid array index is ever negative.Linear search
What is a standard algorithm?
A standard algorithm is a well-known, reusable method for solving a common programming problem — one that has already been designed, tested, and proven to work, rather than something built from scratch every time the same problem appears. Higher requires three standard algorithms working on 1D arrays: linear search (this lesson), and finding a minimum, maximum, or counting occurrences (SDD14). SDD15 then re-runs all of these against arrays of records instead of plain arrays.
How linear search works
Linear search is the simplest standard search algorithm: starting at index 0, it checks each element of an array in order, comparing it to the target value, and stops as soon as a match is found — or, if it reaches the end of the array without a match, concludes the target isn't present at all. The word "linear" describes this straight-line, one-at-a-time scanning; every element up to and including the match must be checked, and in the worst case (target not present, or the very last element), every single element in the array is checked.
Implementing linear search with a found flag
A typical Higher implementation uses a Boolean found flag, starting as False, alongside an index counter starting at 0. A while loop continues as long as the index is still within the array's bounds and the target hasn't been found yet; inside the loop, each element is compared to the target, setting found to True if it matches, or advancing the index if it doesn't. Once the loop ends — either because the target was found, or because the index ran off the end of the array — the found flag (or the final index value) determines what gets returned.
Returning a result: index or sentinel value
Since a search is usually looking for a target's position, not just whether it exists, linear search normally returns the matching index if found. But what should it return if the target isn't in the array at all? No genuine array index is ever negative, so a sentinel value such as -1 is commonly used to signal "not found" — any code calling the search can then check whether the result is -1 before trying to use it as a real index.
Why an incrementing index matters
A very common bug is forgetting to advance the index inside the loop's "no match" branch. If the index is only ever incremented when a match is found, and the target is never actually present, the index never changes and the while condition never becomes false — the loop runs forever, checking the same element over and over. Getting the loop's increment step right, in every branch that doesn't immediately return or set the found flag, is essential to a working search.
Worked examples
"Flapjack":
itemNames = ["Chocolate", "Crisps", "Juice", "Flapjack", "Sweets", "Muffin"]
def linearSearch(array, target):
index = 0
found = False
while index < len(array) and not found:
if array[index] == target:
found = True
else:
index = index + 1
if found:
return index
else:
return -1
result = linearSearch(itemNames, "Flapjack")"Chocolate" (index 0, no match) → "Crisps" (index 1, no match) → "Juice" (index 2, no match) → "Flapjack" (index 3, match — found becomes True, loop stops).result is 3 — confirmed by an actual Python run. Four comparisons were made in total before the match was found.linearSearch function and array, searching for "Kale", which does not appear in itemNames:
result = linearSearch(itemNames, "Kale")
index is incremented all the way to 6 (the length of the array), at which point the while condition index < len(array) becomes False and the loop ends with found still False.result is -1 — confirmed by an actual Python run. All six elements were compared (the worst case) before concluding the target is absent.linearSearch function works unchanged on a numeric array — searching the tuck shop stock levels for the value 15:
stockLevels = [30, 45, 20, 15, 60, 18] result = linearSearch(stockLevels, 15)
== comparison works identically whether the array holds strings or numbers — the algorithm itself doesn't change, only the data does.result is 3 — confirmed by an actual Python run (30, 45, 20 checked and rejected, then 15 found at index 3).linearSearch(itemNames, "Sweets") step by step, recording index, the element compared, and whether it matched:| Iteration | index | array[index] | Match? | found |
|---|---|---|---|---|
| 1 | 0 | Chocolate | No | False |
| 2 | 1 | Crisps | No | False |
| 3 | 2 | Juice | No | False |
| 4 | 3 | Flapjack | No | False |
| 5 | 4 | Sweets | Yes | True |
4.
stockLevels = [30, 45, 20, 15, 60, 18] and the linearSearch function above, what value is returned by linearSearch(stockLevels, 60)? State the index, and how many comparisons are made to reach it.
- Forgetting to increment the index in the "no match" branch. If
indexis never advanced when there isn't a match, the loop never ends — this produces an infinite loop, not just a wrong answer. - Returning
True/Falseinstead of an index. A search is usually expected to say where the target is, not just whether it exists — return the index, using a sentinel value only for "not found". - Using
0as the "not found" sentinel.0is a valid array index (the first element) — using it to mean "not found" makes the first element indistinguishable from "not found".-1is safe because no array index is ever negative. - Continuing to loop after the target is found. Without a found flag (or a
breakstatement) in the loop condition, the search keeps checking elements even after already finding a match, wasting comparisons. - Assuming linear search only works on numbers. The same algorithm works unchanged on strings, or any data type that can be compared with
==.
When tracing a linear search by hand, write out the index and comparison result for every iteration, not just the final one — trace table questions award marks for each correct row, not only the final result. When writing linear search code, state clearly what sentinel value is returned for "not found" and why 0 would not work as that sentinel.
Task Set A — Core questions
itemNames = ["Chocolate", "Crisps", "Juice", "Flapjack", "Sweets", "Muffin"], at what index is "Juice" found by a linear search?stockLevels = [30, 45, 20, 15, 60, 18], what does linearSearch(stockLevels, 100) return?itemNames from Question 2, how many comparisons does linear search make to find "Chocolate"?-1, rather than 0, is used to represent "not found" in a linear search. (3 marks)n?linearSearch that takes an array and a target value as parameters, and returns the index of the target if found, or -1 if it is not found.def linearSearch(array, target):
index = 0
found = False
while index < len(array) and not found:
if array[index] == target:
found = True
else:
index = index + 1
if found:
return index
else:
return -1
Task Set B — Extension
linearSearch stops at the first match it finds. Suggest what would need to change if the target value could appear more than once in the array, and every matching index needed to be found.Higher Computing Science → Software Design & Development → SDD13
Double period. First lesson of the algorithm-specification strand (SDD13–15) — moves away from the tuck shop file-handling scenario's plumbing (SDD11/12) and back onto array logic from SDD5/6, deliberately reusing the same itemNames/stockLevels data for continuity.
Suggested timing: 5 min warm-up + vocab · 25 min notes + search-array visual walkthrough (run the algorithm live in the Python shell, stepping through the array highlighting) · 30 min examples 1–4 including the trace table · 10 min "now you try" · 40 min Task Set A · Task Set B as homework/extension.
Key misconception: pupils very reliably forget to increment the index in the "no match" branch, producing an infinite loop rather than a wrong answer — this is worth demonstrating live (with a safety cap, e.g. printing a message every iteration) so pupils see the loop genuinely never terminating, rather than just being told about it.
Deliberately keeps to a plain 1D array here, not an array of records — SDD15 re-runs this same algorithm against a record field, so introducing that complexity now would blur the two lessons together.
SQA command words covered: describe, explain, write code, trace/complete a trace table.