Topic 3.11: Binary Search | AP CSP Big Idea 3 | APCSExamPrep.com

AP CSP Course Big Idea 3 3.11 Binary Search
3.11
Big Idea 3 • Algorithms & Programming

Binary Search

🕐 ~40 min FREE 📖 6 MCQ questions 🎮 Halving Hunter game 💻 Live Python editor AAP-2.P

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
📈 Exam weight: Binary search is a named algorithm in AAP-2.P and appears in tracing, spot-the-bug, and efficiency questions across Big Idea 3. Forgetting the sorted requirement and miscomputing the middle index are the most common ways students lose these points.
💡 Think about this first

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.

🎯 What the exam expects

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.

✍ Mini Exercise 1 • Predict the output
The list is sorted and the middle index is computed. What does this print?
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.

🎯 The number-of-steps shortcut

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 set low = mid + 1
  • if data[mid] > target: the target must be to the left, so set high = 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.

⚠ Two classic traps

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.

✍ Mini Exercise 2 • Which half survives
The middle value 22 is less than the target 41. Which items does binary search eliminate on this step?
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:

  1. Write the current low and high. Start with low at the first index and high at the last.
  2. Compute mid = (low + high) // 2 using integer division (drop any fraction).
  3. Compare data[mid] to the target. If equal, you are done.
  4. If data[mid] is too small, set low = mid + 1. If it is too big, set high = mid - 1.
  5. Repeat until you find the target or low becomes greater than high, 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.

✍ Mini Exercise 3 • Compute the middle index
Type the exact number this prints.
low = 0
high = 8
mid = (low + high) // 2
print(mid)
prints:

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
📋 Create Performance Task • Binary search as an algorithm you can explain

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:

low <- 1 high <- LENGTH(scores) REPEAT UNTIL (low > high) { mid <- (low + high) / 2 IF (scores[mid] = target) { DISPLAY(mid) } ELSE { IF (scores[mid] < target) { low <- mid + 1 } ELSE { high <- mid - 1 } } }

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 updates low or high to 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 →

📈
MCQ Practice
6 questions • Exam difficulty and above • Predict before you peek
Question 1 of 6Trace
Predict first: at which index does the search land on the target?
The list 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?
low = 0 high = 6 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
Incorrect. Index 3 (value 9) is the first middle checked, but 9 < 18 so the search moves right; it does not stop here.
Incorrect. The second middle of the region 4 to 6 is index 5, not 4. Recompute (4 + 6) // 2.
Correct. First mid is 3 (value 9), and 9 < 18 so low becomes 4. Next mid is (4 + 6) // 2 = 5, and data[5] is 18, a match. It prints 5.
Incorrect. The search finds 18 at index 5 and stops before ever reaching index 6.
Question 2 of 6Spot the bug
This binary search compiles and terminates, but it can give a wrong result. For which list does it fail to find a value that is actually present?
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
Incorrect. This list is sorted, so the binary search works correctly on it.
Correct. The code is fine, but the data must be sorted for binary search to be valid. [9, 2, 7, 1, 5] is unsorted, so a comparison to the middle points the search the wrong way and a present value can be missed.
Incorrect. This list is sorted in increasing order, so binary search behaves correctly.
Incorrect. This list is sorted, so the algorithm searches it correctly.
Question 3 of 6Spot the bug
A student wants binary search to find a value or report not found, but their loop never ends for some targets. Which single change is the bug?
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 else: high = mid - 1
Correct. Setting low = mid can leave low and high stuck on the same index forever, since mid keeps landing on that same spot. Advancing with low = mid + 1 always shrinks the region and guarantees the loop ends.
Incorrect. high = mid - 1 already moves past the middle correctly; changing it to high = mid would create the very problem being described.
Incorrect. Using low < high would stop one step too early and could miss a value; it does not fix the infinite loop.
Incorrect. Regular division would give a non-integer index and cause an error, not fix the endless loop.
Question 4 of 6NOT question
Which statement about binary search is NOT true?
Incorrect. This IS true. Sorted data is exactly what binary search requires, so it is not the answer to a NOT question.
Incorrect. This IS true. Halving the remaining items each step is how binary search works, so it is not the answer.
Correct. This statement is false, so it is the NOT answer. Binary search only works on sorted data; on an unordered list it can return the wrong result.
Incorrect. This IS true. About log2(n) steps is the defining speed of binary search, so it is not the answer.
Question 5 of 6I, II, III
Which of the following statements comparing linear search and binary search are correct?
  • 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.
Incorrect. I is correct, but II is also correct: log2(1000) is about 10 while linear search can take up to 1000 checks.
Correct. I states the sorting requirement accurately and II gives the right step counts. III is false because binary search needs sorted data, and on tiny lists linear search can match it, so "always faster on every list" is wrong.
Incorrect. III is false. Binary search cannot even be used on an unsorted list, so it is not always faster on every list.
Incorrect. III is false, so not all three are correct. The word "always" and "sorted or not" make III wrong.
Question 6 of 6Trace
Predict first: after one comparison, which end of the list is thrown away?
The list 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 = 0 high = 7 mid = (low + high) // 2 # compare data[mid] to target
Correct. mid is (0 + 7) // 2 = 3, and data[3] is 14. Since 5 < 14, the target must be to the left, so high becomes 2 and only indices 0 through 2 remain.
Incorrect. The upper half is eliminated, not kept. Because 5 is less than the middle value 14, the search keeps the lower indices.
Incorrect. A comparison has already happened, so half the list is gone; the full range 0 through 7 is no longer being searched.
Incorrect. Index 3 is the middle that was just checked and rejected; the search continues in the surviving half, not on index 3 alone.
🎮 Lesson Game
Halving Hunter
Trace each binary search step and predict what it displays. 8 rounds.
0
Correct
1/8
Round
0
Streak 🔥
🐛 Python • what is printed?
0/8
correct answers
💻 Live Python Code Editor
Practice Problems
Real Python runs right here in your browser. The first time you press Run, the Python engine loads (a few seconds); after that it is instant. Problems build from guided to Create-Task level. Use Hint if you are stuck, and check your output against the target.
Hints used: 0 • Solutions viewed: 0
Level 1 • Guided
Problem 1 of 8 • compute the middle index
Binary search always starts by finding the middle of the current region. Given low and high, compute mid = (low + high) // 2 and print it. Target output: 3
Level 2 • One comparison
Problem 2 of 8 • which way to go
The list is sorted. Compute the middle index, then print right if the middle value is less than the target (search moves right), otherwise print left. Target output: right
Level 3 • Full search
Problem 3 of 8 • find and print the index
Write a complete binary search that prints the index where target is found. Track low and high, compute mid, and update the correct bound each step. Target output: 5
Level 4 • Fix the bug
Problem 4 of 8 • the two updates are swapped
This search runs and stops, but the two bound updates point the wrong way, so it reports -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
Level 5 • Not found
Problem 5 of 8 • report a missing value
The target is not in this sorted list. Write a binary search that prints the index if the value is found, or the words not found if the region empties out. Target output: not found
Level 6 • Create Task style
Problem 6 of 8 • count the steps
Efficiency questions ask how many checks a search takes. Run a binary search for the target and, instead of the index, print how many times it computes a middle element before finding the value. Target output: 3
Level 7 • Challenge
Problem 7 of 8 • you write the whole search
Open ended. Write the entire binary search yourself. The two inputs are given. Your program must:
  • track low and high over a loop
  • compute mid each step and compare data[mid] to target
  • print the index where target is found
  • print not found if it is missing
Target output: 5
Level 8 • Challenge
Problem 8 of 8 • index and step count
Open ended. Write the entire program yourself. Run a binary search on the given sorted list and print exactly two lines:
  • first line: found at index N where N is the index
  • second line: steps K where K is how many middles were checked
Target output: found at index 7 then steps 4

Frequently Asked Questions

Binary search decides which half of the list to keep by comparing the target to the middle element. That comparison is only meaningful if the elements are in order. On an unsorted list, a smaller middle value does not guarantee the target is to the right, so the search can eliminate the half that actually contains the value and report it as not found.
About 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.
The middle index is 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.
Linear search checks each element one at a time and works on any list, sorted or not, but may need up to n comparisons. Binary search is much faster at about log2(n) steps, but it only works when the data is already sorted. Choose linear search for small or unsorted data and binary search for large sorted data.
When the region being searched empties out, meaning 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.
📦
AP CSP Teacher SuperpackSlides, lesson plans, unit tests for all 5 Big Ideas, $249
Get the Superpack →
🏫
For teachers

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.

Typically responds within 24 hours

Message Sent!

Thanks for reaching out. I'll get back to you within 24 hours.

🏫 Welcome, fellow educator!

I offer curriculum resources, practice materials, and study guides designed for AP CS teachers. Let me know what you're looking for — whether it's classroom materials, a guest speaker, or Teachers Pay Teachers resources.

Email

[email protected]

📚

Courses

AP CSA, CSP, & Cybersecurity

Response Time

Within 24 hours

Prefer email? Reach me directly at [email protected]