Topic 3.11: Binary Search | AP CSP Big Idea 3 | APCSExamPrep.com
Binary Search
After this lesson, you will be able to:
- Explain why binary search requires the data to be sorted
- Track low, high, and mid to trace a binary search step by step
- Determine which half of the list is eliminated after each comparison
- Estimate the number of steps as about log2(n) and contrast it with linear search
- Write a binary search that prints the index found or reports not found
- Describe binary search as a meaningful algorithm for your Create Performance Task
Think about finding a word in a physical dictionary. You do not start at page one and read every entry. You open to the middle, see whether your word comes before or after, and instantly ignore half the book. Repeat a few times and you are there. That is binary search. It is dramatically faster than checking every page, but it only works because a dictionary is already sorted.
What Binary Search Is
Binary search is a fast way to find a value in a list. Instead of checking items one at a time, it repeatedly looks at the middle element and throws away half of the remaining items with a single comparison. Because it can discard half the data on every step, it reaches an answer in far fewer checks than looking at each item in turn.
There is one hard requirement: the data must already be sorted. Binary search only works because comparing the target to the middle element tells you which half the target must be in. If the list is not in order, that comparison tells you nothing, and the search can skip right past the value it is looking for.
data = [2, 5, 8, 12, 16, 23, 38] target = 23 low = 0 high = len(data) - 1 while low <= high: mid = (low + high) // 2 if data[mid] == target: print(mid) break elif data[mid] < target: low = mid + 1 else: high = mid - 1
data <- [2, 5, 8, 12, 16, 23, 38] target <- 23 low <- 1 high <- LENGTH(data) REPEAT UNTIL (low > high) { mid <- (low + high) / 2 IF (data[mid] = target) { DISPLAY(mid) } ELSE { IF (data[mid] < target) { low <- mid + 1 } ELSE { high <- mid - 1 } } }
Searching this sorted list of 7 items for 23, the first middle is index 3 (value 12). Since 12 < 23, everything from index 3 and below is eliminated and the search continues in the upper half. The next middle is index 5 (value 23), a match. Binary search found the value in just two checks, while looking one by one could have taken six.
The CED objective AAP-2.P says binary search "can be used" only on a sorted list, and that it "starts at the middle" and eliminates half the list each iteration. Expect questions that hand you an unsorted list and ask why the search fails, or that ask roughly how many steps a search of n items takes.
data = [3, 7, 11, 20, 25] low = 0 high = 4 mid = (low + high) // 2 print(data[mid])
Linear Search vs Binary Search
Linear search checks each element from the start until it finds the target or runs off the end. It is simple and it works on any list, sorted or not, but for a list of n items it may need up to n comparisons.
# linear search: no sorting needed data = [38, 5, 23, 8, 16, 2, 12] target = 23 found = -1 for i in range(len(data)): if data[i] == target: found = i print(found)
i <- 1 found <- -1 REPEAT LENGTH(data) TIMES { IF (data[i] = target) { found <- i } i <- i + 1 } DISPLAY(found)
Binary search trades that flexibility for speed. It demands a sorted list, but in return it finds a value (or reports it is missing) in about log2(n) steps because each step halves the remaining items. The difference grows fast: a list of 1000 items takes up to 1000 checks with linear search but only about 10 with binary search, since 2 to the 10th power is 1024. Double the list to 2000 items and binary search needs just one more step.
To estimate binary search steps, ask how many times you can halve n before reaching 1. That is log2(n). Handy anchors: 8 items take about 3 steps, 16 take about 4, 1000 take about 10, and 1,000,000 take about 20. Linear search on those same lists could take 8, 16, 1000, and 1,000,000 checks.
How the Halving Works: low, high, and mid
Binary search keeps track of the region of the list still worth searching using two markers: low (the first index of that region) and high (the last index). Each step it computes the middle index as mid = (low + high) // 2 and compares data[mid] to the target. That one comparison decides which half survives:
- if
data[mid]equals the target: found it, stop - if
data[mid] < target: the target must be to the right, so setlow = mid + 1 - if
data[mid] > target: the target must be to the left, so sethigh = mid - 1
data = [4, 9, 15, 22, 30, 41, 55] target = 41 low = 0 high = 6 mid = (low + high) // 2 if data[mid] < target: low = mid + 1 else: high = mid - 1
low <- 1 high <- 7 mid <- (low + high) / 2 IF (data[mid] < target) { low <- mid + 1 } ELSE { high <- mid - 1 }
Here the middle value 22 is less than the target 41, so the entire lower half (indices 0 through 3, including the middle) is eliminated and low jumps to 4. Notice you move past mid with mid + 1 or mid - 1, never leaving it in the region. The loop ends when low passes high, which means the region is empty and the value is not present.
First, binary search on unsorted data is simply wrong; it can report "not found" for a value that is actually in the list. Second, watch the off-by-one: writing low = mid instead of low = mid + 1 can leave low and high stuck on the same spot forever, an infinite loop. Always step past mid.
data = [4, 9, 15, 22, 30, 41, 55] target = 41 low = 0 high = 6 mid = (low + high) // 2 # mid = 3, data[mid] = 22
Tracing Binary Search by Hand
Use one disciplined procedure and these traces become mechanical:
- Write the current low and high. Start with low at the first index and high at the last.
- Compute
mid = (low + high) // 2using integer division (drop any fraction). - Compare
data[mid]to the target. If equal, you are done. - If
data[mid]is too small, setlow = mid + 1. If it is too big, sethigh = mid - 1. - Repeat until you find the target or
lowbecomes greater thanhigh, which means not found.
Counting the number of times you compute a new mid gives the number of steps, which is what step-counting questions ask for. Computing mid correctly is the single most common place students slip, so practice it directly below.
low = 0 high = 8 mid = (low + high) // 2 print(mid)
Key Vocabulary
| Term | Definition | Example |
|---|---|---|
| Binary search | A fast search that repeatedly checks the middle of a sorted list and eliminates half the items | find 23 in ~2 steps |
| Sorted (required) | Elements arranged in order; binary search only works on sorted data | [2, 5, 8, 12, 16] |
| Linear search | Checks each element in order; works on any list; up to n comparisons | scan left to right |
| mid | The middle index checked each step, computed as (low + high) // 2 | (0 + 6) // 2 is 3 |
| low / high | The first and last indices of the region still being searched | low = 4, high = 6 |
| log2(n) | The approximate number of steps binary search needs for n items | 1000 items, ~10 steps |
Binary search is a strong choice for the algorithm your Create Task program develops, because it combines iteration (the loop that keeps narrowing the region) with selection (the comparison that decides which half to keep). That combination is exactly what the rubric asks you to identify and explain in your written responses.
A point-earning example
Suppose your program searches a sorted list of scores for a target value:
In your written response, name the algorithm and explain how the loop and the comparison work together:
- "My algorithm uses binary search, which requires the list to be sorted first."
- "Each iteration computes the middle index and compares
scores[mid]to the target, then updatesloworhighto keep only the half that could contain the target." - "Because it eliminates half the remaining items each time, it finds the value in about log2(n) steps instead of up to n."
The trap to avoid
Do not claim binary search on a list you never sorted. If your data is not in order, the algorithm is incorrect and your explanation loses credibility. Sort first, or describe a linear search instead. See the full Create Task module →
Get a free AP CSP question every day
Join 3,000+ students. Daily practice, study tips, and exam strategies.
data is [1, 4, 6, 9, 13, 18, 21] (indices 0 to 6) and the target is 18. What index does this binary search display?- I. Binary search requires the list to be sorted, while linear search does not.
- II. For a sorted list of 1000 items, binary search needs at most about 10 checks while linear search may need up to 1000.
- III. Binary search is always faster than linear search on every list, sorted or not.
data is [2, 5, 9, 14, 19, 26, 33, 40] (indices 0 to 7) and the target is 5. After the very first comparison of a binary search, which indices remain to be searched?low and high, compute mid = (low + high) // 2 and print it. Target output: 3
right if the middle value is less than the target (search moves right), otherwise print left. Target output: right
target is found. Track low and high, compute mid, and update the correct bound each step. Target output: 5
-1 instead of the real index. Swap them so a smaller middle moves low up and a larger middle moves high down. Target output: 4
not found if the region empties out. Target output: not found
- track
lowandhighover a loop - compute
mideach step and comparedata[mid]totarget - print the index where
targetis found - print
not foundif it is missing
- first line:
found at index Nwhere N is the index - second line:
steps Kwhere K is how many middles were checked
Frequently Asked Questions
log2(n) steps for a list of n items, because each step eliminates half of what remains. A list of 1000 items takes at most about 10 checks, and 1,000,000 items takes about 20. Linear search on those same lists could take up to 1000 and 1,000,000 checks.mid = (low + high) // 2 using integer division, which drops any fraction. For example, with low 0 and high 6, mid is 3. Computing mid is the single most common place students make an error, so it is worth practicing directly.low becomes greater than high, the value is not in the list. A common way to handle this is to store the found index in a variable that starts at -1 and, after the loop, print the index if it changed or print not found otherwise.🔗 Continue studying
The Superpack includes an editable Topic 3.11 slide deck with animated low/high/mid traces, a sorted-versus-unsorted demonstration, a linear-versus-binary step-count worksheet, a spot-the-bug bank, and a unit quiz. View what's included →
Get in Touch
Whether you're a student, parent, or teacher — I'd love to hear from you.
Just want free AP CS resources?
Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.
Message Sent!
Thanks for reaching out. I'll get back to you within 24 hours.
Prefer email? Reach me directly at [email protected]