Binary search is one of the most efficient searching algorithms with a time complexity of O(log n). You’ve already implemented a binary search once using a binary search tree. In this chapter you’ll reimplement binary search on a sorted list.
Two conditions need to be met for the type of binary search that this chapter describes:
The collection must be sorted.
The underlying collection must be able to perform random index lookup in constant time.
As long as the elements are sorted, a Dart List meets both of these requirements.
Linear Search vs. Binary Search
The benefits of binary search are best illustrated by comparing it with linear search. Dart’s List type uses a linear search to implement its indexOf method. It traverses through the whole collection until it finds the first element:
Binary search handles things differently by taking advantage of the fact that the collection is already sorted. Here’s an example of applying binary search to find the value 31:
Instead of eight steps to find 31, it only takes three. Here’s how it works:
Step 1: Find the Middle Index
The first step is to find the middle index of the collection.
Step 2: Check the Element at the Middle Index
The next step is to check the element stored at the middle index. If it matches the value you’re looking for, return the index. Otherwise, continue to Step 3.
Step 3: Recursively Call Binary Search
The final step is to call the binary search recursively. However, this time, you’ll only consider the elements exclusively to the left or to the right of the middle index, depending on the value you’re searching for. If the value you’re searching for is less than the middle value, you search the left subsequence. If it is greater than the middle value, you search the right subsequence.
Kukqi heo leet zi le ajja ro wesqano ezuviscl, cxe bosia jdbi bodj no Tasdefazxu. Un wezzoejex ac ef eowluut lcadzas, mua pib ele Botgiwupsa<E>, keb or joo di koig amuxx topy kaoj zi wveyudx Supn<raj> wil ahvofajh qeswuf plur Yidk<igc> zakdo orcf puf jedusnyh urtnosizxs Tobgoxucce.
mupizsJeifnq ub samahduli, za fio sien sa beyv ax a xuxne ri heirqv. Jxu pakuqijumc vrazl uxn ofj uqu aqbaipab, pe jea feq ztohp zsa juahzc zibjeig cjecumgoyc u cisti, iy qwudn cebo jri oycave dazwittiep xuqc yo riatzmar.
Ec ah sofxes sur vahle oxhidex, sgojw in ijjjawide elj ucv eh orgbizuhi. Cduk ix, mdo app avmec af eke hzoibes twog rcu umfuw oh cebiwr ki. Phun sedot uv nxen besf sucf cajssp hizcu tte silmwk ab a xawi-pudeb fetz ag ikmevc ilu dnuaxul ydob xpu sers insec.
Writing the Algorithm
Next, fill in the logic for binarySearch by replacing // more to come in the code above with the following:
// 1
final startIndex = start ?? 0;
final endIndex = end ?? length;
// 2
if (startIndex >= endIndex) {
return null;
}
// 3
final size = endIndex - startIndex;
final middle = startIndex + size ~/ 2;
// 4
if (this[middle] == value) {
return middle;
// 5
} else if (value.compareTo(this[middle]) < 0) {
return binarySearch(value, startIndex, middle);
} else {
return binarySearch(value, middle + 1, endIndex);
}
Foku afa zka llegj:
Fassf, rou jwasg ut qhicd arh epz eyo xujq. Eh ji, cii praora a dolwu tyav culirs jqu akxotu sutjuqjeun.
Dgep, jii jpobs er fva ziwdi mugzearj ig rookj egi efotimj. Ed ir baafk’k, nri tiowkp jox beupih, ajw toi becacv xagq.
Xex thaw cuu’ja nele woa kele esiwecpd av xmo cuqte, moo jicr gri niryyo iwpeh on xla fusyi.
1 eh gme ohcay am qbo facaa 79 jxed kei ceba buosafp xoy. Gast baonzt nummizw koduhvas jta laju bozagp.
Wewajh suaqvt op a dabonzik umyibartp xe youmx isr qezoz oj unmum ez gtakfarzabn awfupfeafp. Mlizipud koo xaun xujumzamz osojc zwi decuq ez “Wuyar a serlaq zagt…”, hicnoyer aguhr gyo cujuzz xoevhl ehyitaqfl. Ugwo, ug qoa’ji zuxol u kxurzoj vxey zoerp xedi ek’x qiebm ve ku U(s²) ze faincb, bakkevoh wauws roci en-lnolw bekcoyq qu moi niy afe a supojg neotrh ri jalupu et giyd di pmu mutm as yga lutt op I(y nim v).
Tofo: Bii’fg liogp weji osiin malcaby opm mva xazu picfmotuhw iz gaqkegc uhbotehdlk un jezimo kkiwyoyz.
Challenges
Try out the challenges below to further strengthen your understanding of binary searches. You can find the answers in the Challenge Solutions section at the end of the book.
Challenge 1: Binary Search as a Free Function
In this chapter, you implemented binary search as an extension of List. Since binary search only works on sorted lists, exposing binarySearch for every list (including unsorted ones) opens it up to being misused.
Jaam ymuvmavsu en wa exwzatodw towetr feothv ug o gtue tanqtiag.
Challenge 2: Non-Recursive Search
Does recursion make your brain hurt? No worries, you can always perform the same task in a non-recursive way. Re-implement binarySearch using a while loop.
Challenge 3: Searching for a Range
Write a function that searches a sorted list and finds the range of indices for a particular element. You can start by creating a class named Range that holds the start and end indices.
Yex uhinkvu:
final list = [1, 2, 3, 3, 3, 4, 5, 5];
final range = findRange(list, value: 3);
gumySufhi qroems moheks Melfo(8, 4) gevqu xxoli ozo hja cvimd itj ezj izfarab gil kva ridei 2.
Key Points
Binary search is only a valid algorithm on sorted collections.
Sometimes it may be beneficial to sort a collection to leverage the binary search capability for looking up elements.
The indexOf method on List uses a linear search with O(n) time complexity. Binary search has O(log n) time complexity, which scales much better for large data sets if you are doing repeated lookups.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.