Searching
Binary Search First Occurrence
Find the first copy of a duplicated target by recording matches and continuing to search the left half.
Algorithm
execution replay
The checked-in replay follows the language-neutral state table for `search-binary-first`.
cross-language comparison
This Bash DSA version keeps the same data and final output as every other DSA book in this wave.
Basic Implementation
basic.sh
Replay: real traced execution (multi-file project)
#!/usr/bin/env bash
set -euo pipefail
arr=(1 2 4 4 4 7 9)
target=4
lo=0
hi=$((${#arr[@]} - 1))
result=-1
while [ "$lo" -le "$hi" ]; do
mid=$((lo + (hi - lo) / 2))
if [ "${arr[mid]}" -eq "$target" ]; then
result=$mid
hi=$((mid - 1))
elif [ "${arr[mid]}" -lt "$target" ]; then
lo=$((mid + 1))
else
hi=$((mid - 1))
fi
done
echo "$result"
arr ← [1, 2, 4, 4, 4, 7, 9], target ← 4, result ← -1
1#!/usr/bin/env bash2set -euo pipefailvalues this step[1, 2, 4, 4, 4, 7, 9]arr4target-1resulthi ← 2, mid ← 3, result ← 3
8while [ "$lo" -le "$hi" ]; do9 mid=$((lo + (hi - lo) / 2))10 if [ "${arr[mid]}" -eq "$target" ]; thenvalues this step6 → 2hi3mid3result0lolo ← 2, mid ← 1
8while [ "$lo" -le "$hi" ]; do9 mid=$((lo + (hi - lo) / 2))10 if [ "${arr[mid]}" -eq "$target" ]; thenvalues this step0 → 2lo1mid2hi3resulthi ← 1, result ← 2, mid ← 2
8while [ "$lo" -le "$hi" ]; do9 mid=$((lo + (hi - lo) / 2))10 if [ "${arr[mid]}" -eq "$target" ]; thenvalues this step2 → 1hi3 → 2result2mid2lostdout ← 2
18done19echo "$result"values this step2stdout2result
Complexity
- Time: O(log n)
- Space: O(1)
Implementation notes
arr=(1 2 4 4 4 7 9)is a Bash indexed array, and this lesson uses zero-based positions.hi=$((${#arr[@]} - 1))reads the array length with${#arr[@]}and sets the initial upper bound to index6.lo=0,hi=6, andresult=-1seed the search window and the not-found sentinel.mid=$((lo + (hi - lo) / 2))computes the midpoint with Bash arithmetic expansion.[ "${arr[mid]}" -eq "$target" ]tests for a numeric match, and[ "${arr[mid]}" -lt "$target" ]tests whether the current value is too small.- On a match,
result=$midrecords the current index, thenhi=$((mid - 1))keeps searching left for the first duplicate. - When the value is too small,
lo=$((mid + 1))moves the lower bound right.
Replay steps
start: lo=0, hi=6, result=-1
mid=3: arr[3]=4 matches -> result=3, hi=2
mid=1: arr[1]=2 is too small -> lo=2
mid=2: arr[2]=4 matches -> result=2, hi=1
stop: lo=2, hi=1 -> print 2
echo "$result"prints exactly2.