Binary search: Difference between revisions
m
→{{header|Chapel}}
m (→{{header|Phix}}: added syntax colouring the hard way) |
LalaithMeren (talk | contribs) |
||
(57 intermediate revisions by 24 users not shown) | |||
Line 1:
{{task|Classic CS problems and programs}}
A binary search divides a range of values into halves, and continues to narrow down the field of search until the unknown value is found. It is the classic example of a "divide and conquer" algorithm.
Line 146:
:* [http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken].
<br><br>
=={{header|11l}}==
<
V low = 0
V high = l.len - 1
Line 159 ⟶ 158:
E
R mid
R -1</
=={{header|360 Assembly}}==
<
BINSEAR CSECT
USING BINSEAR,R13 base register
Line 232 ⟶ 230:
XDEC DS CL12 temp
YREGS
END BINSEAR</
{{out}}
<pre>
Line 238 ⟶ 236:
229 found at 23
</pre>
=={{header|8080 Assembly}}==
Line 247 ⟶ 244:
Test code is included, which will loop through the values [0..255] and report for each number whether it was in the array or not.
<
jmp test
Line 349 ⟶ 346:
rst 0
</syntaxhighlight>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program binSearch64.s */
Line 589 ⟶ 586:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
<pre>
Value find at index : 0
Line 601 ⟶ 598:
Value find at index : 8
</pre>
=={{header|ACL2}}==
<
(cons name
(compress1 name
Line 664 ⟶ 660:
(populate-array-ordered
(defarray 'haystack *dim* 0)
*dim*)))</
=={{header|Action!}}==
<syntaxhighlight lang="action!">INT FUNC BinarySearch(INT ARRAY a INT len,value)
INT low,high,mid
low=0 high=len-1
WHILE low<=high
DO
mid=low+(high-low) RSH 1
IF a(mid)>value THEN
high=mid-1
ELSEIF a(mid)<value THEN
low=mid+1
ELSE
RETURN (mid)
FI
OD
RETURN (-1)
PROC Test(INT ARRAY a INT len,value)
INT i
Put('[)
FOR i=0 TO len-1
DO
PrintI(a(i))
IF i<len-1 THEN Put(32) FI
OD
i=BinarySearch(a,len,value)
Print("] ") PrintI(value)
IF i<0 THEN
PrintE(" not found")
ELSE
Print(" found at index ")
PrintIE(i)
FI
RETURN
PROC Main()
INT ARRAY a=[65530 0 1 2 5 6 8 9]
Test(a,8,6)
Test(a,8,-6)
Test(a,8,9)
Test(a,8,-10)
Test(a,8,10)
Test(a,8,7)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Binary_search.png Screenshot from Atari 8-bit computer]
<pre>
[-6 0 1 2 5 6 8 9] 6 found at index 5
[-6 0 1 2 5 6 8 9] -6 found at index 0
[-6 0 1 2 5 6 8 9] 9 found at index 7
[-6 0 1 2 5 6 8 9] -10 not found
[-6 0 1 2 5 6 8 9] 10 not found
[-6 0 1 2 5 6 8 9] 7 not found
</pre>
=={{header|Ada}}==
Both solutions are generic. The element can be of any comparable type (such that the operation < is visible in the instantiation scope of the function Search). Note that the completion condition is different from one given in the pseudocode example above. The example assumes that the array index type does not overflow when mid is incremented or decremented beyond the corresponding array bound. This is a wrong assumption for Ada, where array bounds can start or end at the very first or last value of the index type. To deal with this, the exit condition is rather directly expressed as crossing the corresponding array bound by the coming interval middle.
;Recursive:
<
procedure Test_Recursive_Binary_Search is
Line 722 ⟶ 774:
Test ((2, 4, 6, 8, 9), 9);
Test ((2, 4, 6, 8, 9), 5);
end Test_Recursive_Binary_Search;</
;Iterative:
<
procedure Test_Binary_Search is
Line 779 ⟶ 831:
Test ((2, 4, 6, 8, 9), 9);
Test ((2, 4, 6, 8, 9), 5);
end Test_Binary_Search;</
Sample output:
<pre>
Line 789 ⟶ 841:
2 4 6 8 9 does not contain 5
</pre>
=={{header|ALGOL 68}}==
<
MODE ELEMENT = STRING;
Line 839 ⟶ 890:
test search(recursive binary search, test cases)
)
END</
{{out}}
Shows iterative search output - recursive search output is the same.
Line 848 ⟶ 899:
"ZZZ" near index 8
</pre>
=={{header|ALGOL W}}==
Ieterative and recursive binary search procedures, from the pseudo code. Finds the left most occurance/insertion point.
<
% recursive binary search, left most insertion point %
integer procedure binarySearchLR ( integer array A ( * )
Line 899 ⟶ 949:
end for_s
end
end.</
{{out}}
<pre>
Line 911 ⟶ 961:
iterative search suggests insert 24 at 5
</pre>
=={{header|APL}}==
{{works with|Dyalog APL}}
<
⎕IO(⍺{ ⍝ first lower bound is start of array
⍵<⍺:⍬ ⍝ if high < low, we didn't find it
Line 924 ⟶ 973:
}⍵)⎕IO+(≢⍺)-1 ⍝ first higher bound is top of array
}
</syntaxhighlight>
=={{header|AppleScript}}==
<
repeat until (l = r)
set m to (l + r) div 2
Line 952 ⟶ 1,000:
set theList to {1, 2, 3, 3, 5, 7, 7, 8, 9, 10, 11, 12}
return test(7, theList, 4, 11) & linefeed & test(7, theList, 7, 12) & linefeed & test(7, theList, 1, 5)</
{{output}}
Line 959 ⟶ 1,007:
The first occurrence of 7 in range 7 thru 12 of the list is at index 7
7 is not in range 1 thru 5 of the list"</pre>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
Line 1,239 ⟶ 1,286:
iMagicNumber: .int 0xCCCCCCCD
</syntaxhighlight>
=={{header|Arturo}}==
<
if high < low -> return ø
mid: shr low+high 1
case [val]
when? [< arr
when? [> arr
else -> return mid
]
Line 1,262 ⟶ 1,308:
if? not? null? i -> print ["found" v "at index:" i]
else -> print [v "not found"]
]</
{{out}}
Line 1,271 ⟶ 1,317:
found 24324 at index: 24
99999 not found</pre>
=={{header|AutoHotkey}}==
<
StringSplit, A, array, `, ; creates associative array
MsgBox % x := BinarySearch(A, 4, 1, A0) ; Recursive
Line 1,305 ⟶ 1,350:
}
Return not_found
}</
=={{header|AWK}}==
{{works with|Gawk}}
Line 1,312 ⟶ 1,356:
{{works with|Nawk}}
'''Recursive'''
<
if (right < left) return 0
middle = int((right + left) / 2)
Line 1,319 ⟶ 1,363:
return binary_search(array, value, left, middle - 1)
return binary_search(array, value, middle + 1, right)
}</
'''Iterative'''
<
while (left <= right) {
middle = int((right + left) / 2)
Line 1,329 ⟶ 1,373:
}
return 0
}</
=={{header|Axe}}==
'''Iterative'''
Line 1,336 ⟶ 1,379:
BSEARCH takes 3 arguments: a pointer to the start of the data, the data to find, and the length of the array in bytes.
<
0→L
r₃-1→H
Line 1,351 ⟶ 1,394:
End
-1
Return</
=={{header|BASIC}}==
Line 1,357 ⟶ 1,400:
{{works with|FreeBASIC}}
{{works with|RapidQ}}
<
DIM middle AS Integer
Line 1,373 ⟶ 1,416:
END SELECT
END IF
END FUNCTION</
'''Iterative'''
{{works with|FreeBASIC}}
{{works with|RapidQ}}
<
DIM middle AS Integer
Line 1,393 ⟶ 1,436:
WEND
binary_search = 0
END FUNCTION</
'''Testing the function'''
The following program can be used to test both recursive and iterative version.
<
DIM idx AS Integer
Line 1,419 ⟶ 1,462:
search test(), 4
search test(), 8
search test(), 20</
Output:
Value 4 not found
Value 8 found at index 5
Value 20 found at index 10
==={{header|Applesoft BASIC}}===
{{works with|QBasic}}
{{works with|Chipmunk Basic}}
{{works with|GW-BASIC}}
{{works with|MSX BASIC}}
{{works with|Quite BASIC}}
<syntaxhighlight lang="qbasic">100 REM Binary search
110 HOME : REM 110 CLS for Chipmunk Basic, MSX Basic, QBAsic and Quite BASIC
111 REM REMOVE line 110 for Minimal BASIC
120 DIM a(10)
130 LET n = 10
140 FOR j = 1 TO n
150 READ a(j)
160 NEXT j
170 REM Sorted data
180 DATA -31,0,1,2,2,4,65,83,99,782
190 LET x = 2
200 GOSUB 440
210 GOSUB 310
220 LET x = 5
230 GOSUB 440
240 GOSUB 310
250 GOTO 720
300 REM Print result
310 PRINT x;
320 IF i < 0 THEN 350
330 PRINT " is at index "; i; "."
340 RETURN
350 PRINT " is not found."
360 RETURN
400 REM Binary search algorithm
410 REM N - number of elements
420 REM X - searched element
430 REM Result: I - index of X
440 LET l = 0
450 LET h = n - 1
460 LET f = 0
470 LET m = l
480 IF l > h THEN 590
490 IF f <> 0 THEN 590
500 LET m = l + INT((h - l) / 2)
510 IF a(m) >= x THEN 540
520 LET l = m + 1
530 GOTO 480
540 IF a(m) <= x THEN 570
550 LET h = m - 1
560 GOTO 480
570 LET f = 1
580 GOTO 480
590 IF f = 0 THEN 700
600 LET i = m
610 RETURN
700 LET i = -1
710 RETURN
720 END</syntaxhighlight>
==={{header|ASIC}}===
<syntaxhighlight lang="basic">
REM Binary search
DIM A(10)
REM Sorted data
DATA -31, 0, 1, 2, 2, 4, 65, 83, 99, 782
FOR I = 0 TO 9
READ A(I)
NEXT I
N = 10
X = 2
GOSUB DoBinarySearch:
GOSUB PrintResult:
X = 5
GOSUB DoBinarySearch:
GOSUB PrintResult:
END
PrintResult:
PRINT X;
IF IndX >= 0 THEN
PRINT " is at index ";
PRINT IndX;
PRINT "."
ELSE
PRINT " is not found."
ENDIF
RETURN
DoBinarySearch:
REM Binary search algorithm
REM N - number of elements
REM X - searched element
REM Result: IndX - index of X
L = 0
H = N - 1
Found = 0
Loop:
IF L > H THEN AfterLoop:
IF Found <> 0 THEN AfterLoop:
REM (L <= H) and (Found = 0)
M = H - L
M = M / 2
M = L + M
REM So, M = L + (H - L) / 2
IF A(M) < X THEN
L = M + 1
ELSE
IF A(M) > X THEN
H = M - 1
ELSE
Found = 1
ENDIF
ENDIF
GOTO Loop:
AfterLoop:
IF Found = 0 THEN
IndX = -1
ELSE
IndX = M
ENDIF
RETURN
</syntaxhighlight>
{{out}}
<pre>
2 is at index 4.
5 is not found.
</pre>
==={{header|BASIC256}}===
====Recursive Solution====
<syntaxhighlight lang="basic256">function binarySearchR(array, valor, lb, ub)
if ub < lb then
return false
else
mitad = floor((lb + ub) / 2)
if valor < array[mitad] then return binarySearchR(array, valor, lb, mitad-1)
if valor > array[mitad] then return binarySearchR(array, valor, mitad+1, ub)
if valor = array[mitad] then return mitad
end if
end function</syntaxhighlight>
====Iterative Solution====
<syntaxhighlight lang="basic256">function binarySearchI(array, valor)
lb = array[?,]
ub = array[?]
while lb <= ub
mitad = floor((lb + ub) / 2)
begin case
case array[mitad] > valor
ub = mitad - 1
case array[mitad] < valor
lb = mitad + 1
else
return mitad
end case
end while
return false
end function</syntaxhighlight>
'''Test:'''
<syntaxhighlight lang="basic256">items = 10e5
dim array(items)
for n = 0 to items-1 : array[n] = n : next n
t0 = msec
print binarySearchI(array, 3)
print msec - t0; " millisec"
t1 = msec
print binarySearchR(array, 3, array[?,], array[?])
print msec - t1; " millisec"
end</syntaxhighlight>
{{out}}
<pre>3
839 millisec
3
50 millisec</pre>
==={{header|BBC BASIC}}===
<
array%() = 7, 14, 21, 28, 35, 42, 49, 56, 63, 70
Line 1,448 ⟶ 1,665:
H% /= 2
UNTIL H%=0
IF S%=A%(B%) THEN = B% ELSE = -1</
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
{{works with|QBasic}}
{{works with|GW-BASIC}}
<syntaxhighlight lang="qbasic">100 rem Binary search
110 cls
120 dim a(10)
130 n% = 10
140 for i% = 0 to 9 : read a(i%) : next i%
150 rem Sorted data
160 data -31,0,1,2,2,4,65,83,99,782
170 x = 2 : gosub 280
180 gosub 230
190 x = 5 : gosub 280
200 gosub 230
210 end
220 rem Print result
230 print x;
240 if indx% >= 0 then print "is at index ";str$(indx%);"." else print "is not found."
250 return
260 rem Binary search algorithm
270 rem N% - number of elements; X - searched element; Result: INDX% - index of X
280 l% = 0 : h% = n%-1 : found% = 0
290 while (l% <= h%) and not found%
300 m% = l%+int((h%-l%)/2)
310 if a(m%) < x then l% = m%+1 else if a(m%) > x then h% = m%-1 else found% = -1
320 wend
330 if found% = 0 then indx% = -1 else indx% = m%
340 return</syntaxhighlight>
==={{header|Craft Basic}}===
<syntaxhighlight lang="basic">'iterative binary search example
define size = 0, search = 0, flag = 0, value = 0
define middle = 0, low = 0, high = 0
dim list[2, 3, 5, 6, 8, 10, 11, 15, 19, 20]
arraysize size, list
let value = 4
gosub binarysearch
let value = 8
gosub binarysearch
let value = 20
gosub binarysearch
end
sub binarysearch
let search = 1
let middle = 0
let low = 0
let high = size
do
if low <= high then
let middle = int((high + low ) / 2)
let flag = 1
if value < list[middle] then
let high = middle - 1
let flag = 0
endif
if value > list[middle] then
let low = middle + 1
let flag = 0
endif
if flag = 1 then
let search = 0
endif
endif
loop low <= high and search = 1
if search = 1 then
let middle = 0
endif
if middle < 1 then
print "not found"
endif
if middle >= 1 then
print "found at index ", middle
endif
return</syntaxhighlight>
{{out| Output}}<pre>not found
found at index 4
found at index 9</pre>
==={{header|FreeBASIC}}===
<
'returns the index of the target number, or -1 if it is not in the array
dim as uinteger lo = lbound(array), hi = ubound(array), md = (lo + hi)\2
Line 1,462 ⟶ 1,791:
wend
return -1
end function</
=== {{header|GW-BASIC}} ===
{{trans|ASIC}}
{{works with|BASICA}}
<syntaxhighlight lang="gwbasic">
10 REM Binary search
20 DIM A(10)
30 N% = 10
40 FOR I% = 0 TO 9: READ A(I%): NEXT I%
50 REM Sorted data
60 DATA -31, 0, 1, 2, 2, 4, 65, 83, 99, 782
70 X = 2: GOSUB 500
80 GOSUB 200
90 X = 5: GOSUB 500
100 GOSUB 200
110 END
190 REM Print result
200 PRINT X;
210 IF INDX% >= 0 THEN PRINT "is at index"; STR$(INDX%);"." ELSE PRINT "is not found."
220 RETURN
480 REM Binary search algorithm
490 REM N% - number of elements; X - searched element; Result: INDX% - index of X
500 L% = 0: H% = N% - 1: FOUND% = 0
510 WHILE (L% <= H%) AND NOT FOUND%
520 M% = L% + (H% - L%) \ 2
530 IF A(M%) < X THEN L% = M% + 1 ELSE IF A(M%) > X THEN H% = M% - 1 ELSE FOUND% = -1
540 WEND
550 IF FOUND% = 0 THEN INDX% = -1 ELSE INDX% = M%
560 RETURN
</syntaxhighlight>
{{out}}
<pre>
2 is at index 4.
5 is not found.
</pre>
==={{header|IS-BASIC}}===
<
110 RANDOMIZE
120 NUMERIC ARR(1 TO 20)
Line 1,491 ⟶ 1,855:
340 LOOP WHILE BO<=UP AND T(K)<>N
350 IF BO<=UP THEN LET SEARCH=K
360 END DEF</
==={{header|Liberty BASIC}}===
<syntaxhighlight lang="lb">
dim theArray(100)
for i = 1 to 100
theArray(i) = i
next i
print binarySearch(80,30,90)
wait
FUNCTION binarySearch(val, lo, hi)
IF hi < lo THEN
binarySearch = 0
ELSE
middle = int((hi + lo) / 2):print middle
if val < theArray(middle) then binarySearch = binarySearch(val, lo, middle-1)
if val > theArray(middle) then binarySearch = binarySearch(val, middle+1, hi)
if val = theArray(middle) then binarySearch = middle
END IF
END FUNCTION
</syntaxhighlight>
==={{header|Minimal BASIC}}===
{{trans|ASIC}}
{{works with|Bywater BASIC|3.00}}
{{works with|Commodore BASIC|3.5}}
{{works with|MSX Basic|any}}
{{works with|Nascom ROM BASIC|4.7}}
<syntaxhighlight lang="basic">
10 REM Binary search
20 LET N = 10
30 FOR I = 1 TO N
40 READ A(I)
50 NEXT I
60 REM Sorted data
70 DATA -31, 0, 1, 2, 2, 4, 65, 83, 99, 782
80 LET X = 2
90 GOSUB 500
100 GOSUB 200
110 LET X = 5
120 GOSUB 500
130 GOSUB 200
140 END
190 REM Print result
200 PRINT X;
210 IF I1 < 0 THEN 240
220 PRINT "is at index"; I1; "."
230 RETURN
240 PRINT "is not found."
250 RETURN
460 REM Binary search algorithm
470 REM N - number of elements
480 REM X - searched element
490 REM Result: I1 - index of X
500 LET L = 0
510 LET H = N-1
520 LET F = 0
530 LET M = L
540 IF L > H THEN 650
550 IF F <> 0 THEN 650
560 LET M = L+INT((H-L)/2)
570 IF A(M) >= X THEN 600
580 LET L = M+1
590 GOTO 540
600 IF A(M) <= X THEN 630
610 LET H = M-1
620 GOTO 540
630 LET F = 1
640 GOTO 540
650 IF F = 0 THEN 680
660 LET I1 = M
670 RETURN
680 LET I1 = -1
690 RETURN
</syntaxhighlight>
==={{header|MSX Basic}}===
The [[#Minimal_BASIC|Minimal BASIC]] solution works without any changes.
==={{header|Palo Alto Tiny BASIC}}===
{{trans|ASIC}}
<syntaxhighlight lang="basic">
10 REM BINARY SEARCH
20 LET N=10
30 REM SORTED DATA
40 LET @(1)=-31,@(2)=0,@(3)=1,@(4)=2,@(5)=2
50 LET @(6)=4,@(7)=65,@(8)=83,@(9)=99,@(10)=782
60 LET X=2;GOSUB 500
70 GOSUB 200
80 LET X=5;GOSUB 500
90 GOSUB 200
100 STOP
190 REM PRINT RESULT
200 IF J<0 PRINT #1,X," IS NOT FOUND.";RETURN
210 PRINT #1,X," IS AT INDEX ",J,".";RETURN
460 REM BINARY SEARCH ALGORITHM
470 REM N - NUMBER OF ELEMENTS
480 REM X - SEARCHED ELEMENT
490 REM RESULT: J - INDEX OF X
500 LET L=0,H=N-1,F=0,M=L
510 IF L>H GOTO 570
520 IF F#0 GOTO 570
530 LET M=L+(H-L)/2
540 IF @(M)<X LET L=M+1;GOTO 510
550 IF @(M)>X LET H=M-1;GOTO 510
560 LET F=1;GOTO 510
570 IF F=0 LET J=-1;RETURN
580 LET J=M;RETURN
</syntaxhighlight>
{{out}}
<pre>
2 IS AT INDEX 4.
5 IS NOT FOUND.
</pre>
==={{header|PureBasic}}===
Both recursive and iterative procedures are included and called in the code below.
<syntaxhighlight lang="purebasic">#Recursive = 0 ;recursive binary search method
#Iterative = 1 ;iterative binary search method
#NotFound = -1 ;search result if item not found
;Recursive
Procedure R_BinarySearch(Array a(1), value, low, high)
Protected mid
If high < low
ProcedureReturn #NotFound
EndIf
mid = (low + high) / 2
If a(mid) > value
ProcedureReturn R_BinarySearch(a(), value, low, mid - 1)
ElseIf a(mid) < value
ProcedureReturn R_BinarySearch(a(), value, mid + 1, high)
Else
ProcedureReturn mid
EndIf
EndProcedure
;Iterative
Procedure I_BinarySearch(Array a(1), value, low, high)
Protected mid
While low <= high
mid = (low + high) / 2
If a(mid) > value
high = mid - 1
ElseIf a(mid) < value
low = mid + 1
Else
ProcedureReturn mid
EndIf
Wend
ProcedureReturn #NotFound
EndProcedure
Procedure search (Array a(1), value, method)
Protected idx
Select method
Case #Iterative
idx = I_BinarySearch(a(), value, 0, ArraySize(a()))
Default
idx = R_BinarySearch(a(), value, 0, ArraySize(a()))
EndSelect
Print(" Value " + Str(Value))
If idx < 0
PrintN(" not found")
Else
PrintN(" found at index " + Str(idx))
EndIf
EndProcedure
#NumElements = 9 ;zero based count
Dim test(#NumElements)
DataSection
Data.i 2, 3, 5, 6, 8, 10, 11, 15, 19, 20
EndDataSection
;fill the test array
For i = 0 To #NumElements
Read test(i)
Next
If OpenConsole()
PrintN("Recursive search:")
search(test(), 4, #Recursive)
search(test(), 8, #Recursive)
search(test(), 20, #Recursive)
PrintN("")
PrintN("Iterative search:")
search(test(), 4, #Iterative)
search(test(), 8, #Iterative)
search(test(), 20, #Iterative)
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
Input()
CloseConsole()
EndIf</syntaxhighlight>
Sample output:
<pre>
Recursive search:
Value 4 not found
Value 8 found at index 4
Value 20 found at index 9
Iterative search:
Value 4 not found
Value 8 found at index 4
Value 20 found at index 9
</pre>
==={{header|Quite BASIC}}===
{{works with|QBasic}}
{{works with|Applesoft BASIC}}
{{works with|Chipmunk Basic}}
{{works with|GW-BASIC}}
{{works with|Minimal BASIC}}
{{works with|MSX BASIC}}
<syntaxhighlight lang="qbasic">100 REM Binary search
110 CLS : REM 110 HOME for Applesoft BASIC : REM REMOVE for Minimal BASIC
120 DIM a(10)
130 LET n = 10
140 FOR j = 1 TO n
150 READ a(j)
160 NEXT j
170 REM Sorted data
180 DATA -31,0,1,2,2,4,65,83,99,782
190 LET x = 2
200 GOSUB 440
210 GOSUB 310
220 LET x = 5
230 GOSUB 440
240 GOSUB 310
250 GOTO 720
300 REM Print result
310 PRINT x;
320 IF i < 0 THEN 350
330 PRINT " is at index "; i; "."
340 RETURN
350 PRINT " is not found."
360 RETURN
400 REM Binary search algorithm
410 REM N - number of elements
420 REM X - searched element
430 REM Result: I - index of X
440 LET l = 0
450 LET h = n - 1
460 LET f = 0
470 LET m = l
480 IF l > h THEN 590
490 IF f <> 0 THEN 590
500 LET m = l + INT((h - l) / 2)
510 IF a(m) >= x THEN 540
520 LET l = m + 1
530 GOTO 480
540 IF a(m) <= x THEN 570
550 LET h = m - 1
560 GOTO 480
570 LET f = 1
580 GOTO 480
590 IF f = 0 THEN 700
600 LET i = m
610 RETURN
700 LET i = -1
710 RETURN
720 END</syntaxhighlight>
==={{header|Run BASIC}}===
'''Recursive'''
<syntaxhighlight lang="runbasic">dim theArray(100)
global theArray
for i = 1 to 100
theArray(i) = i
next i
print binarySearch(80,30,90)
FUNCTION binarySearch(val, lo, hi)
IF hi < lo THEN
binarySearch = 0
ELSE
middle = (hi + lo) / 2
if val < theArray(middle) then binarySearch = binarySearch(val, lo, middle-1)
if val > theArray(middle) then binarySearch = binarySearch(val, middle+1, hi)
if val = theArray(middle) then binarySearch = middle
END IF
END FUNCTION</syntaxhighlight>
==={{header|TI-83 BASIC}}===
<syntaxhighlight lang="ti83b">PROGRAM:BINSEARC
:Disp "INPUT A LIST:"
:Input L1
:SortA(L1)
:Disp "INPUT A NUMBER:"
:Input A
:1→L
:dim(L1)→H
:int(L+(H-L)/2)→M
:While L<H and L1(M)≠A
:If A>M
:Then
:M+1→L
:Else
:M-1→H
:End
:int(L+(H-L)/2)→M
:End
:If L1(M)=A
:Then
:Disp A
:Disp "IS AT POSITION"
:Disp M
:Else
:Disp A
:Disp "IS NOT IN"
:Disp L1</syntaxhighlight>
==={{header|uBasic/4tH}}===
{{trans|Run BASIC}}
The overflow is fixed - which is a bit of overkill, since uBasic/4tH has only one array of 256 elements.
<syntaxhighlight lang="text">For i = 1 To 100 ' Fill array with some values
@(i-1) = i
Next
Print FUNC(_binarySearch(50,0,99)) ' Now find value '50'
End ' and prints its index
_binarySearch Param(3) ' value, start index, end index
Local(1) ' The middle of the array
If c@ < b@ Then ' Ok, signal we didn't find it
Return (-1)
Else
d@ = SHL(b@ + c@, -1) ' Prevent overflow (LOL!)
If a@ < @(d@) Then Return (FUNC(_binarySearch (a@, b@, d@-1)))
If a@ > @(d@) Then Return (FUNC(_binarySearch (a@, d@+1, c@)))
If a@ = @(d@) Then Return (d@) ' We found it, return index!
EndIf</syntaxhighlight>
==={{header|VBA}}===
'''Recursive version''':
<syntaxhighlight lang="vb">Public Function BinarySearch(a, value, low, high)
'search for "value" in ordered array a(low..high)
'return index point if found, -1 if not found
If high < low Then
BinarySearch = -1 'not found
Exit Function
End If
midd = low + Int((high - low) / 2) ' "midd" because "Mid" is reserved in VBA
If a(midd) > value Then
BinarySearch = BinarySearch(a, value, low, midd - 1)
ElseIf a(midd) < value Then
BinarySearch = BinarySearch(a, value, midd + 1, high)
Else
BinarySearch = midd
End If
End Function</syntaxhighlight>
Here are some test functions:
<syntaxhighlight lang="vb">Public Sub testBinarySearch(n)
Dim a(1 To 100)
'create an array with values = multiples of 10
For i = 1 To 100: a(i) = i * 10: Next
Debug.Print BinarySearch(a, n, LBound(a), UBound(a))
End Sub
Public Sub stringtestBinarySearch(w)
'uses BinarySearch with a string array
Dim a
a = Array("AA", "Maestro", "Mario", "Master", "Mattress", "Mister", "Mistress", "ZZ")
Debug.Print BinarySearch(a, w, LBound(a), UBound(a))
End Sub</syntaxhighlight>
and sample output:
<pre>
stringtestBinarySearch "Master"
3
testBinarySearch "Master"
-1
testBinarySearch 170
17
stringtestBinarySearch 170
-1
stringtestBinarySearch "Moo"
-1
stringtestBinarySearch "ZZ"
7
</pre>
'''Iterative version:'''
<syntaxhighlight lang="vb">Public Function BinarySearch2(a, value)
'search for "value" in array a
'return index point if found, -1 if not found
low = LBound(a)
high = UBound(a)
Do While low <= high
midd = low + Int((high - low) / 2)
If a(midd) = value Then
BinarySearch2 = midd
Exit Function
ElseIf a(midd) > value Then
high = midd - 1
Else
low = midd + 1
End If
Loop
BinarySearch2 = -1 'not found
End Function</syntaxhighlight>
==={{header|VBScript}}===
{{trans|BASIC}}
'''Recursive'''
<syntaxhighlight lang="vb">Function binary_search(arr,value,lo,hi)
If hi < lo Then
binary_search = 0
Else
middle=Int((hi+lo)/2)
If value < arr(middle) Then
binary_search = binary_search(arr,value,lo,middle-1)
ElseIf value > arr(middle) Then
binary_search = binary_search(arr,value,middle+1,hi)
Else
binary_search = middle
Exit Function
End If
End If
End Function
'Tesing the function.
num_range = Array(2,3,5,6,8,10,11,15,19,20)
n = CInt(WScript.Arguments(0))
idx = binary_search(num_range,n,LBound(num_range),UBound(num_range))
If idx > 0 Then
WScript.StdOut.Write n & " found at index " & idx
WScript.StdOut.WriteLine
Else
WScript.StdOut.Write n & " not found"
WScript.StdOut.WriteLine
End If</syntaxhighlight>
{{out}}
'''Note: Array index starts at 0.'''
<pre>
C:\>cscript /nologo binary_search.vbs 4
4 not found
C:\>cscript /nologo binary_search.vbs 8
8 found at index 4
C:\>cscript /nologo binary_search.vbs 20
20 found at index 9
</pre>
==={{header|Visual Basic .NET}}===
'''Iterative'''
<syntaxhighlight lang="vbnet">Function BinarySearch(ByVal A() As Integer, ByVal value As Integer) As Integer
Dim low As Integer = 0
Dim high As Integer = A.Length - 1
Dim middle As Integer = 0
While low <= high
middle = (low + high) / 2
If A(middle) > value Then
high = middle - 1
ElseIf A(middle) < value Then
low = middle + 1
Else
Return middle
End If
End While
Return Nothing
End Function</syntaxhighlight>
'''Recursive'''
<syntaxhighlight lang="vbnet">Function BinarySearch(ByVal A() As Integer, ByVal value As Integer, ByVal low As Integer, ByVal high As Integer) As Integer
Dim middle As Integer = 0
If high < low Then
Return Nothing
End If
middle = (low + high) / 2
If A(middle) > value Then
Return BinarySearch(A, value, low, middle - 1)
ElseIf A(middle) < value Then
Return BinarySearch(A, value, middle + 1, high)
Else
Return middle
End If
End Function</syntaxhighlight>
==={{header|Yabasic}}===
{{trans|Lua}}
<syntaxhighlight lang="yabasic">sub floor(n)
return int(n + .5)
end sub
sub binarySearch(list(), value)
local low, high, mid
low = 1 : high = arraysize(list(), 1)
while(low <= high)
mid = floor((low + high) / 2)
if list(mid) > value then
high = mid - 1
elsif list(mid) < value then
low = mid + 1
else
return mid
end if
wend
return false
end sub
ITEMS = 10e6
dim list(ITEMS)
for n = 1 to ITEMS
list(n) = n
next n
print binarySearch(list(), 3)
print peek("millisrunning")</syntaxhighlight>
==={{header|ZX Spectrum Basic}}===
{{trans|FreeBASIC}}
Iterative method:
<syntaxhighlight lang="zxbasic">10 DATA 2,3,5,6,8,10,11,15,19,20
20 DIM t(10)
30 FOR i=1 TO 10
40 READ t(i)
50 NEXT i
60 LET value=4: GO SUB 100
70 LET value=8: GO SUB 100
80 LET value=20: GO SUB 100
90 STOP
100 REM Binary search
110 LET lo=1: LET hi=10
120 IF lo>hi THEN LET idx=0: GO TO 170
130 LET middle=INT ((hi+lo)/2)
140 IF value<t(middle) THEN LET hi=middle-1: GO TO 120
150 IF value>t(middle) THEN LET lo=middle+1: GO TO 120
160 LET idx=middle
170 PRINT "Value ";value;
180 IF idx=0 THEN PRINT " not found": RETURN
190 PRINT " found at index ";idx: RETURN
</syntaxhighlight>
=={{header|Batch File}}==
<
@echo off & setlocal enabledelayedexpansion
Line 1,543 ⟶ 2,467:
echo . binchop required !b! iterations
endlocal & exit /b 0
</syntaxhighlight>
=={{header|BQN}}==
BQN has two builtin functions for binary search: <code>⍋</code>(Bins Up) and <code>⍒</code>(Bins Down). This is a recursive method.
<syntaxhighlight lang="bqn">BSearch ← {
BS ⟨a, value⟩:
BS ⟨a, value, 0, ¯1+≠a⟩;
BS ⟨a, value, low, high⟩:
mid ← ⌊2÷˜low+high
{
high<low ? ¯1;
(mid⊑a)>value ? BS ⟨a, value, low, mid-1⟩;
(mid⊑a)<value ? BS ⟨a, value, mid+1, high⟩;
mid
}
}
•Show BSearch ⟨8‿30‿35‿45‿49‿77‿79‿82‿87‿97, 97⟩</syntaxhighlight>
<syntaxhighlight lang="text">9</syntaxhighlight>
=={{header|Brat}}==
<
true? high < low
{ null }
Line 1,576 ⟶ 2,518:
null? index
{ p "Not found" }
{ p "Found at index: #{index}" }</
=={{header|Bruijn}}==
<syntaxhighlight lang="bruijn">
:import std/Combinator .
:import std/Math .
:import std/List .
:import std/Option .
binary-search [y [[[[[2 <? 3 none go]]]]] (+0) --(∀0) 0]
go [compare-case eq lt gt (2 !! 0) 1] /²(3 + 2)
eq some 0
lt 5 4 --0 2 1
gt 5 ++0 3 2 1
# example using sorted list of x^3, x=[-50,50]
find [[map-or "not found" [0 : (1 !! 0)] (binary-search 0 1)] lst]
lst take (+100) ((\pow (+3)) <$> (iterate ++‣ (-50)))
:test (find (+100)) ("not found")
:test ((head (find (+125))) =? (+55)) ([[1]])
:test ((head (find (+117649))) =? (+99)) ([[1]])
</syntaxhighlight>
=={{header|C}}==
<
int bsearch (int *a, int n, int x) {
Line 1,620 ⟶ 2,584:
int x = 2;
int i = bsearch(a, n, x);
printf("%d is at index %d.\n", x, i);
else
printf("%d is not found.\n", x);
x = 5;
i = bsearch_r(a, x, 0, n - 1);
printf("%d is at index %d.\n", x, i);
else
printf("%d is not found.\n", x);
return 0;
}
</syntaxhighlight>
{{output}}
<pre>
2 is at index 4.
5 is
</pre>
=={{header|C sharp|C#}}==
'''Recursive'''
<
using System;
Line 1,705 ⟶ 2,674:
}
}
}</
'''Iterative'''
<
using System;
Line 1,779 ⟶ 2,748:
}
}
}</
'''Example'''
<
using System;
Line 1,823 ⟶ 2,792:
#endif
}
}</
'''Output'''
Line 1,859 ⟶ 2,828:
glb = 13
lub = 21</pre>
=={{header|C++}}==
'''Recursive'''
<
template <class T> int binsearch(const T array[], int low, int high, T value) {
if (high < low) {
Line 1,888 ⟶ 2,856:
return 0;
}</
'''Iterative'''
<
int binSearch(const T arr[], int len, T what) {
int low = 0;
Line 1,904 ⟶ 2,872:
}
return -1; // indicate not found
}</
'''Library'''
C++'s Standard Template Library has four functions for binary search, depending on what information you want to get. They all need<syntaxhighlight lang
The <code>lower_bound()</code> function returns an iterator to the first position where a value could be inserted without violating the order; i.e. the first element equal to the element you want, or the place where it would be inserted.
<
The <code>upper_bound()</code> function returns an iterator to the last position where a value could be inserted without violating the order; i.e. one past the last element equal to the element you want, or the place where it would be inserted.
<
The <code>equal_range()</code> function returns a pair of the results of <code>lower_bound()</code> and <code>upper_bound()</code>.
<
Note that the difference between the bounds is the number of elements equal to the element you want.
The <code>binary_search()</code> function returns true or false for whether an element equal to the one you want exists in the array. It does not give you any information as to where it is.
<
=={{header|Chapel}}==
'''iterative''' -- almost a direct translation of the pseudocode
<
{
var
while (low <= high)
{
var mid = (low + high) / 2;
Line 1,940 ⟶ 2,909:
}
writeln(binsearch([3, 4, 6, 9, 11], 9));</
{{out}}
Line 1,947 ⟶ 2,916:
=={{header|Clojure}}==
'''Recursive'''
<
([coll t]
(bsearch coll 0 (dec (count coll)) t))
Line 1,962 ⟶ 2,931:
; we've found our target
; so return its index
(= mth t) m)))))</
=={{header|CLU}}==
<syntaxhighlight lang="clu">% Binary search in an array
% If the item is found, returns `true' and the index;
% if the item is not found, returns `false' and the leftmost insertion point
% The datatype must support the < and > operators.
binary_search = proc [T: type] (a: array[T], val: T) returns (bool, int)
where T has lt: proctype (T,T) returns (bool),
T has gt: proctype (T,T) returns (bool)
low: int := array[T]$low(a)
high: int := array[T]$high(a)
while low <= high do
mid: int := low + (high - low) / 2
if a[mid] > val then
high := mid - 1
elseif a[mid] < val then
low := mid + 1
else
return (true, mid)
end
end
return (false, low)
end binary_search
% Test the binary search on an array
start_up = proc ()
po: stream := stream$primary_output()
% primes up to 20 (note that arrays are 1-indexed by default)
primes: array[int] := array[int]$[2,3,5,7,11,13,17,19]
% binary search for each number from 1 to 20
for n: int in int$from_to(1,20) do
i: int
found: bool
found, i := binary_search[int](primes, n)
if found then
stream$putl(po, int$unparse(n)
|| " found at location "
|| int$unparse(i));
else
stream$putl(po, int$unparse(n)
|| " not found, would be inserted at location "
|| int$unparse(i));
end
end
end start_up</syntaxhighlight>
{{out}}
<pre>1 not found, would be inserted at location 1
2 found at location 1
3 found at location 2
4 not found, would be inserted at location 3
5 found at location 3
6 not found, would be inserted at location 4
7 found at location 4
8 not found, would be inserted at location 5
9 not found, would be inserted at location 5
10 not found, would be inserted at location 5
11 found at location 5
12 not found, would be inserted at location 6
13 found at location 6
14 not found, would be inserted at location 7
15 not found, would be inserted at location 7
16 not found, would be inserted at location 7
17 found at location 7
18 not found, would be inserted at location 8
19 found at location 8
20 not found, would be inserted at location 9</pre>
=={{header|COBOL}}==
COBOL's <code>SEARCH ALL</code> statement is implemented as a binary search on most implementations.
<
IDENTIFICATION DIVISION.
PROGRAM-ID. binary-search.
Line 1,983 ⟶ 3,020:
END-SEARCH
.
END PROGRAM binary-search.</
=={{header|CoffeeScript}}==
'''Recursive'''
<
do recurse = (low = 0, high = xs.length - 1) ->
mid = Math.floor (low + high) / 2
Line 1,994 ⟶ 3,030:
when xs[mid] > x then recurse low, mid - 1
when xs[mid] < x then recurse mid + 1, high
else mid</
'''Iterative'''
<
[low, high] = [0, xs.length - 1]
while low <= high
Line 2,004 ⟶ 3,040:
when xs[mid] < x then low = mid + 1
else return mid
NaN</
'''Test'''
<
odds = (it for it in [1..n] by 2)
result = (it for it in \
Line 2,013 ⟶ 3,049:
console.assert "#{result}" is "#{[0...odds.length]}"
console.log "#{odds} are odd natural numbers"
console.log "#{it} is ordinal of #{odds[it]}" for it in result</
Output:
<pre>1,3,5,7,9,11 are odd natural numbers"
Line 2,022 ⟶ 3,058:
4 is ordinal of 9
5 is ordinal of 11</pre>
=={{header|Common Lisp}}==
'''Iterative'''
<
(let ((low 0)
(high (1- (length array))))
Line 2,038 ⟶ 3,073:
(setf low (1+ middle)))
(t (return middle)))))))</
'''Recursive'''
<
(if (< high low)
nil
Line 2,051 ⟶ 3,086:
(binary-search value array (1+ middle) high))
(t middle)))))</
=={{header|Crystal}}==
'''Recursive'''
<
def binary_search(val, low = 0, high = (size - 1))
return nil if high < low
Line 2,079 ⟶ 3,113:
puts "#{val} not found in array"
end
end</
'''Iterative'''
<
def binary_search_iterative(val)
low, high = 0, size - 1
Line 2,109 ⟶ 3,143:
puts "#{val} not found in array"
end
end</
{{out}}
<pre>
Line 2,118 ⟶ 3,152:
99999 not found in array
</pre>
=={{header|D}}==
<
/// Recursive.
Line 2,160 ⟶ 3,193:
// Standard Binary Search:
!items.equalRange(x).empty);
}</
{{out}}
<pre> 1 false false false
Line 2,170 ⟶ 3,203:
=={{header|Delphi}}==
See [[#Pascal]].
=={{header|E}}==
<
def binarySearch(collection, value) {
var low := 0
Line 2,185 ⟶ 3,217:
}
return null
}</
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
proc binSearch val . a[] res .
while
low = mid + 1
.
.
.
a[] = [ 2 4 6 8 9 ]
print r
</syntaxhighlight>
=={{header|Eiffel}}==
Line 2,211 ⟶ 3,244:
The following solution is based on the one described in: C. A. Furia, B. Meyer, and S. Velder. ''Loop Invariants: Analysis, Classification, and Examples''. ACM Computing Surveys, 46(3), Article 34, January 2014. (Also available at http://arxiv.org/abs/1211.4470). It includes detailed loop invariants and pre- and postconditions, which make the running time linear (instead of logarithmic) when full contract checking is enabled.
<
APPLICATION
Line 2,330 ⟶ 3,363:
end
end</
=={{header|Elixir}}==
<
def search(list, value), do: search(List.to_tuple(list), value, 0, length(list)-1)
Line 2,354 ⟶ 3,386:
index -> IO.puts "found #{val} at index #{index}"
end
end)</
{{out}}
Line 2,364 ⟶ 3,396:
99999 not found in list
</pre>
=={{header|Emacs Lisp}}==
<
(defun binary-search (value array)
(let ((low 0)
Line 2,376 ⟶ 3,407:
((< (aref array middle) value)
(setf low (1+ middle)))
(t (cl-return middle)))))))</
=={{header|EMal}}==
<syntaxhighlight lang="emal">
type BinarySearch:Recursive
fun binarySearch = int by List values, int value
fun recurse = int by int low, int high
if high < low do return -1 end
int mid = low + (high - low) / 2
return when(values[mid] > value,
recurse(low, mid - 1),
when(values[mid] < value,
recurse(mid + 1, high),
mid))
end
return recurse(0, values.length - 1)
end
type BinarySearch:Iterative
fun binarySearch = int by List values, int value
int low = 0
int high = values.length - 1
while low <= high
int mid = low + (high - low) / 2
if values[mid] > value do high = mid - 1
else if values[mid] < value do low = mid + 1
else do return mid
end
end
return -1
end
List values = int[0, 1, 4, 5, 6, 7, 8, 9, 12, 26, 45, 67, 78,
90, 98, 123, 211, 234, 456, 769, 865, 2345, 3215, 14345, 24324]
List matches = int[24324, 32, 78, 287, 0, 42, 45, 99999]
for each int match in matches
writeLine("index is: " +
BinarySearch:Recursive.binarySearch(values, match) + ", " +
BinarySearch:Iterative.binarySearch(values, match))
end
</syntaxhighlight>
{{out}}
<pre>
index is: 24, 24
index is: -1, -1
index is: 12, 12
index is: -1, -1
index is: 0, 0
index is: -1, -1
index is: 10, 10
index is: -1, -1
</pre>
=={{header|Erlang}}==
<
%% Author: Abhay Jain
Line 2,405 ⟶ 3,485:
Mid
end
end.</
=={{header|Euphoria}}==
===Recursive===
<
integer mid, cmp
if high < low then
Line 2,424 ⟶ 3,503:
end if
end if
end function</
===Iterative===
<
integer low, high, mid, cmp
low = 1
Line 2,442 ⟶ 3,521:
end while
return 0 -- not found
end function</
=={{header|F Sharp|F#}}==
Generic recursive version, using #light syntax:
<
if (high < low) then
null
Line 2,457 ⟶ 3,535:
binarySearch (myArray, mid+1, high, value)
else
myArray.[mid]</
=={{header|Factor}}==
Factor already includes a binary search in its standard library. The following code offers an interface compatible with the requirement of this task, and returns either the index of the element if it has been found or f otherwise.
<
: binary-search ( seq elt -- index/f )
[ [ <=> ] curry search ] keep = [ drop f ] unless ;</
=={{header|FBSL}}==
FBSL has built-in QuickSort() and BSearch() functions:
<
DIM va[], sign = {1, -1}, toggle
Line 2,489 ⟶ 3,565:
" in ", GetTickCount() - gtc, " milliseconds"
PAUSE</
Output:<pre>Loading ... done in 906 milliseconds
Sorting ... done in 547 milliseconds
Line 2,498 ⟶ 3,574:
'''Iterative:'''
<
DIM va[]
Line 2,526 ⟶ 3,602:
WEND
RETURN -1
END FUNCTION</
Output:<pre>Loading ... done in 391 milliseconds
3141592.65358979 found at index 1000000 in 62 milliseconds
Line 2,533 ⟶ 3,609:
'''Recursive:'''
<
DIM va[]
Line 2,557 ⟶ 3,633:
END IF
RETURN midp
END FUNCTION</
Output:<pre>Loading ... done in 390 milliseconds
3141592.65358979 found at index 1000000 in 938 milliseconds
Press any key to continue...</pre>
=={{header|Forth}}==
This version is designed for maintaining a sorted array. If the item is not found, then then location returned is the proper insertion point for the item. This could be used in an optimized [[Insertion sort]], for example.
<
' - is (compare) \ default to numbers
Line 2,595 ⟶ 3,670:
10 probe \ 0 11
11 probe \ -1 11
12 probe \ 0 99</
=={{header|Fortran}}==
'''Recursive'''
In ISO Fortran 90 or later use a RECURSIVE function and ARRAY SECTION argument:
<
real, intent(in) :: a(:), value
integer :: bsresult, mid
Line 2,617 ⟶ 3,691:
bsresult = mid ! SUCCESS!!
end if
end function binarySearch_R</
'''Iterative'''
<br>
In ISO Fortran 90 or later use an ARRAY SECTION POINTER:
<
integer :: binarySearch_I
real, intent(in), target :: a(:)
Line 2,643 ⟶ 3,717:
end if
end do
end function binarySearch_I</
===Iterative, exclusive bounds, three-way test.===
Line 2,654 ⟶ 3,728:
The use of "exclusive" bounds simplifies the adjustment of the bounds: the appropriate bound simply receives the value of P, there is ''no'' + 1 or - 1 adjustment ''at every step''; similarly, the determination of an empty span is easy, and avoiding the risk of integer overflow via (L + R)/2 is achieved at the same time. The "inclusive" bounds version by contrast requires ''two'' manipulations of L and R ''at every step'' - once to see if the span is empty, and a second time to locate the index to test.
<
Careful: it is surprisingly difficult to make this neat, due to vexations when N = 0 or 1.
REAL X,A(*) !Where is X in array A(1:N)?
Line 2,673 ⟶ 3,747:
Curse it!
5 FINDI = -L !X is not found. Insert it at L + 1, i.e. at A(1 - FINDI).
END FUNCTION FINDI !A's values need not be all different, merely in order. </
[[File:BinarySearch.Flowchart.png]]
Line 2,685 ⟶ 3,759:
====An alternative version====
<
Careful: it is surprisingly difficult to make this neat, due to vexations when N = 0 or 1.
REAL X,A(*) !Where is X in array A(1:N)?
Line 2,704 ⟶ 3,778:
Curse it!
5 FINDI = -L !X is not found. Insert it at L + 1, i.e. at A(1 - FINDI).
END FUNCTION FINDI !A's values need not be all different, merely in order. </
The point of this is that the IF-test is going to initiate some jumps, so why not arrange that one of the bound adjustments needs no subsequent jump to the start of the next iteration - in the first version, both bound adjustments needed such a jump, the GO TO 1 statements. This was done by shifting the code for label 2 up to precede the code for label 1 - and removing its now pointless GO TO 1 (executed each time), but adding an initial GO TO 1, executed once only. This sort of change is routine when manipulating spaghetti code...
Line 2,719 ⟶ 3,793:
Incidentally, the exclusive-bounds version leads to a good version of the interpolation search (whereby the probe position is interpolated, not just in the middle of the span), unlike the version based on inclusive-bounds. Further, the unsourced offering in Wikipedia contains a bug - try searching an array of two equal elements for that value.
=={{header|Futhark}}==
{{incorrect|Futhark|Futhark's syntax has changed, so this example will not compile}}
Line 2,725 ⟶ 3,798:
Straightforward translation of imperative iterative algorithm.
<syntaxhighlight lang="futhark">
fun main(as: [n]int, value: int): int =
let low = 0
Line 2,739 ⟶ 3,812:
else (mid, mid-1) -- Force termination.
in low
</syntaxhighlight>
=={{header|GAP}}==
<
local low, high, mid;
low := 1;
Line 2,764 ⟶ 3,836:
# fail
Find(u, 35);
# 5</
=={{header|Go}}==
'''Recursive''':
<
if high < low {
return -1
Line 2,779 ⟶ 3,850:
}
return mid
}</
'''Iterative''':
<
low := 0
high := len(a) - 1
Line 2,795 ⟶ 3,866:
}
return -1
}</
'''Library''':
<
//...
sort.SearchInts([]int{0,1,4,5,6,7,8,9}, 6) // evaluates to 4</
Exploration of library source code shows that it uses the <tt>mid = low + (high - low) / 2</tt> technique to avoid overflow.
There are also functions <code>sort.SearchFloat64s()</code>, <code>sort.SearchStrings()</code>, and a very general <code>sort.Search()</code> function that allows you to binary search a range of numbers based on any condition (not necessarily just search for an index of an element in an array).
=={{header|Groovy}}==
Both solutions use ''sublists'' and a tracking offset in preference to "high" and "low".
====Recursive Solution====
<
def binSearchR
//define binSearchR closure.
Line 2,823 ⟶ 3,893:
: [index: offset + m]
}
</syntaxhighlight>
====Iterative Solution====
<
def a = aList
def offset = 0
Line 2,842 ⟶ 3,912:
}
return ["insertion point": offset]
}</
Test:
<
def random = new Random()
while (a.size() < 20) { a << random.nextInt(30) }
Line 2,860 ⟶ 3,930:
println """
Answer: ${answers[0]}, : ${source[answers[0].values().iterator().next()]}"""
}</
Output:
<pre>[1, 2, 5, 8, 9, 10, 11, 14, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29]
Line 2,873 ⟶ 3,943:
Trial #5. Looking for: 32
Answer: [insertion point:20], : null</pre>
=={{header|Haskell}}==
===Recursive algorithm===
The algorithm itself, parametrized by an "interrogation" predicate ''p'' in the spirit of the explanation above:
<
-- BINARY SEARCH --------------------------------------------------------------
Line 2,929 ⟶ 3,998:
case found of
Nothing -> "' Not found"
Just x -> "' found at index " ++ show x</
{{Out}}
<pre>'mu' found at index 9</pre>
Line 2,936 ⟶ 4,005:
A common optimisation of recursion is to delegate the main computation to a helper function with simpler type signature. For the option type of the return value, we could also use an Either as an alternative to a Maybe.
<
-- BINARY SEARCH USING A HELPER FUNCTION WITH A SIMPLER TYPE SIGNATURE
Line 2,981 ⟶ 4,050:
("' " ++)
(("' found at index " ++) . show)
(findIndexBinary (compare needle) haystack)</
{{Out}}
<pre>'lambda' found at index 8</pre>
Line 2,991 ⟶ 4,060:
It returns the result of applying '''f''' until '''p''' holds.
<
-- BINARY SEARCH USING THE ITERATIVE ALGORITHM
Line 3,040 ⟶ 4,109:
("' " ++)
(("' found at index " ++) . show)
(findIndexBinary_ (compare needle) haystack)</
{{Out}}
<pre>'kappa' found at index 7</pre>
=={{header|HicEst}}==
<
array = NINT( RAN(n) )
Line 3,076 ⟶ 4,144:
ENDIF
ENDDO
END</
<
5 has position 0 in 0 0 1 2 3 3 4 6 7 8</
=={{header|Hoon}}==
<
=/ lo=@ud 0
=/ hi=@ud (dec (lent arr))
Line 3,090 ⟶ 4,157:
?: (lth x val) $(hi (dec mid))
?: (gth x val) $(lo +(mid))
mid</
=={{header|Icon}} and {{header|Unicon}}==
Only a recursive solution is shown here.
<
if *A = 0 then fail
mid := *A/2 + 1
Line 3,104 ⟶ 4,170:
}
return mid
end</
A program to test this is:
<
target := integer(!args) | 3
every put(A := [], 1 to 18 by 2)
Line 3,118 ⟶ 4,184:
every writes(!A," ")
write()
end</
with some sample runs:
<pre>
Line 3,150 ⟶ 4,216:
->
</pre>
=={{header|J}}==
J already includes a binary search primitive (<code>I.</code>). The following code offers an interface compatible with the requirement of this task, and returns either the index of the element if it has been found or 'Not Found' otherwise:
<
'''Examples:'''
<
6
2 3 5 6 8 10 11 15 19 20 bs 12
Not Found</
Direct tacit iterative and recursive versions to compare to other implementations follow:
'''Iterative'''
<
f=. &({::) NB. Fetching the contents of a box
o=. @: NB. Composing verbs (functions)
Line 3,174 ⟶ 4,239:
return=. (M f) o ((<@:('Not Found'"_) M} ]) ^: (_ ~: L f))
bs=. return o (squeeze o midpoint ^: (L f <: H f) ^:_) o LowHigh o boxes</
'''Recursive'''
<
f=. &({::) NB. Fetching the contents of a box
o=. @: NB. Composing verbs (functions)
Line 3,186 ⟶ 4,251:
recur=. (X f bs Y f ; L f ; (_1 + M f))`(M f)`(X f bs Y f ; (1 + M f) ; H f)@.case
bs=. (recur o midpoint`('Not Found'"_) @. (H f < L f) o boxes) :: ([ bs ] ; 0 ; (<: o # o [))</
=={{header|Java}}==
'''Iterative'''
<
public static int binarySearch(int[] nums, int check) {
Line 3,218 ⟶ 4,282:
}
}
}</
'''Recursive'''
<
public static int binarySearch(int[] haystack, int needle, int lo, int hi) {
Line 3,249 ⟶ 4,313:
}
}
}</
'''Library'''
When the key is not found, the following functions return <code>~insertionPoint</code> (the bitwise complement of the index where the key would be inserted, which is guaranteed to be a negative number).
For arrays:
<
int index = Arrays.binarySearch(array, thing);
Line 3,261 ⟶ 4,325:
// for objects, also optionally accepts an additional comparator argument:
int index = Arrays.binarySearch(array, thing, comparator);
int index = Arrays.binarySearch(array, startIndex, endIndex, thing, comparator);</
For Lists:
<
int index = Collections.binarySearch(list, thing);
int index = Collections.binarySearch(list, thing, comparator);</
=={{header|JavaScript}}==
===ES5===
Recursive binary search implementation
<
if (hi < lo) { return null; }
Line 3,283 ⟶ 4,346:
}
return mid;
}</
Iterative binary search implementation
<
var mid, lo = 0,
hi = a.length - 1;
Line 3,301 ⟶ 4,364:
}
return null;
}</
===ES6===
Line 3,307 ⟶ 4,370:
Recursive and iterative, by composition of pure functions, with tests and output:
<
'use strict';
Line 3,463 ⟶ 4,526:
// MAIN ---
return main();
})();</
{{Out}}
<pre>[
Line 3,504 ⟶ 4,567:
]
]</pre>
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
jq and gojq both have a binary-search builtin named `bsearch`.
In the following, a parameterized filter for performing a binary search of a sorted JSON array is defined.
Specifically, binarySearch(value) will return an index (i.e. offset) of `value` in the array if the array contains the value, and otherwise (-1 - ix), where ix is the insertion point, if the value cannot be found.
binarySearch will always terminate. The inner function is recursive.
<syntaxhighlight lang="jq">def binarySearch(value):
# To avoid copying the array, simply pass in the current low and high offsets
def binarySearch(low; high):
Line 3,518 ⟶ 4,588:
end
end;
binarySearch(0; length-1);</
Example:<
{{Out}}
2
=={{header|Jsish}}==
<
Binary search, in Jsish, based on Javascript entry
Tectonics: jsish -u -time true -verbose true binarySearch.jsi
Line 3,576 ⟶ 4,646:
puts('Iterative:', Util.times(function() { binarySearchIterative(arr, 42); }, 100), 'µs');
puts('Recursive:', Util.times(function() { binarySearchRecursive(arr, 42, 0, arr.length - 1); }, 100), 'µs');
}</
{{out}}
Line 3,587 ⟶ 4,657:
>
[PASS] binarySearch.jsi (165 ms)</pre>
=={{header|Julia}}==
{{works with|Julia|0.6}}
'''Iterative''':
<
low = 1
high = length(lst)
Line 3,605 ⟶ 4,674:
end
return 0
end</
'''Recursive''':
<
if isempty(lst) return 0 end
if low ≥ high
Line 3,625 ⟶ 4,694:
return mid
end
end</
=={{header|K}}==
Recursive:
<syntaxhighlight lang="k">
bs:{[a;t]
if[0=#a; :_n];
Line 3,644 ⟶ 4,712:
{bs[v;x]}' v
0 1 2 3 4 5 6 7 8 9
</syntaxhighlight>
=={{header|Kotlin}}==
<
var hi = size - 1
var lo = 0
Line 3,684 ⟶ 4,751:
r = a.recursiveBinarySearch(target, 0, a.size)
println(if (r < 0) "$target not found" else "$target found at index $r")
}</
{{Out}}
<pre>6 found at index 4
Line 3,690 ⟶ 4,757:
6 found at index 4
250 not found</pre>
=={{header|Lambdatalk}}==
Can be tested in (http://lambdaway.free.fr)[http://lambdaway.free.fr/lambdaway/?view=binary_search]
<
{def BS
{def BS.r {lambda {:a :v :i0 :i1}
Line 3,722 ⟶ 4,788:
{BS {B} 100} -> 100 is not found
{BS {B} 12345} -> 12345 is at array[6172]
</syntaxhighlight>
=={{header|Logo}}==
<
if :upper < :lower [output []]
localmake "mid int (:lower + :upper) / 2
Line 3,754 ⟶ 4,797:
if item :mid :a < :value [output bsearch :value :a :mid+1 :upper]
output :mid
end</
=={{header|Lolcode}}==
'''Iterative'''
<
HAI 1.2
CAN HAS STDIO?
Line 3,846 ⟶ 4,888:
KTHXBYE
end</
Output
<pre>
Line 3,858 ⟶ 4,900:
I CAN HAS UR CHEEZBURGER NAO?
</pre>
=={{header|Lua}}==
'''Iterative'''
<
local low = 1
local high = #list
Line 3,872 ⟶ 4,913:
end
return false
end</
'''Recursive'''
<
local function search(low, high)
if low > high then return false end
Line 3,883 ⟶ 4,924:
end
return search(1,#list)
end</
=={{header|M4}}==
<syntaxhighlight lang="m4">define(`notfound',`-1')dnl
define(`midsearch',`ifelse(defn($1[$4]),$2,$4,
`ifelse(eval(defn($1[$4])>$2),1,`binarysearch($1,$2,$3,decr($4))',`binarysearch($1,$2,incr($4),$5)')')')dnl
define(`binarysearch',`ifelse(eval($4<$3),1,notfound,`midsearch($1,$2,$3,eval(($3+$4)/2),$4)')')dnl
dnl
define(`setrange',`ifelse(`$3',`',$2,`define($1[$2],$3)`'setrange($1,incr($2),shift(shift(shift($@))))')')dnl
define(`asize',decr(setrange(`a',1,1,3,5,7,11,13,17,19,23,29)))dnl
dnl
binarysearch(`a',5,1,asize)
binarysearch(`a',8,1,asize)</syntaxhighlight>
Output:
<pre>
3
-1
</pre>
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
\\ binary search
const N=10
Line 3,932 ⟶ 4,988:
Print A()
</syntaxhighlight>
=={{header|MACRO-11}}==
This deals with the overflow problem when calculating `mid` by using a `ROR` (rotate right) instruction to divide by two, which rotates the carry flag back into the result. `ADD` produces a 17-bit result, with the 17th bit in the carry flag.
<syntaxhighlight lang="macro11"> .TITLE BINRTA
.MCALL .TTYOUT,.PRINT,.EXIT
; TEST CODE
BINRTA::CLR R5
1$: MOV R5,R0
ADD #'0,R0
.TTYOUT
MOV R5,R0
MOV #DATA,R1
MOV #DATEND,R2
JSR PC,BINSRC
BEQ 2$
.PRINT #4$
BR 3$
2$: .PRINT #5$
3$: INC R5
CMP R5,#^D10
BLT 1$
.EXIT
4$: .ASCII / NOT/
5$: .ASCIZ / FOUND/
.EVEN
; TEST DATA
DATA: .WORD 1, 2, 3, 5, 7
DATEND = . + 2
; BINARY SEARCH
; INPUT: R0 = VALUE, R1 = LOW PTR, R2 = HIGH PTR
; OUTPUT: ZF SET IF VALUE FOUND; R1 = INSERTION POINT
BINSRC: BR 3$
1$: MOV R1,R3
ADD R2,R3
ROR R3
CMP (R3),R0
BGE 2$
ADD #2,R3
MOV R3,R1
BR 3$
2$: SUB #2,R3
MOV R3,R2
3$: CMP R2,R1
BGE 1$
CMP (R1),R0
RTS PC
.END BINRTA</syntaxhighlight>
{{out}}
<pre>0 NOT FOUND
1 FOUND
2 FOUND
3 FOUND
4 NOT FOUND
5 FOUND
6 NOT FOUND
7 FOUND
8 NOT FOUND
9 NOT FOUND</pre>
=={{header|Maple}}==
Line 3,955 ⟶ 5,055:
'''Recursive'''
<
description "recursive binary search";
if high < low then
Line 3,969 ⟶ 5,069:
end if
end if
end proc:</
'''Iterative'''
<
description "iterative binary search";
local low, high;
Line 3,988 ⟶ 5,088:
end do;
FAIL
end proc:</
We can use either lists or Arrays (or Vectors) for the first argument for these.
<
> P := [seq]( ithprime( i ), i = 1 .. N ):
> BinarySearch( P, 12, 1, N ); # recursive version
Line 4,006 ⟶ 5,106:
> PP[ 3 ];
13</
=={{header|Mathematica}} / {{header|Wolfram Language}}==
'''Recursive'''
<
Module[{mid = lo + Round@((hi - lo)/2)},
If[hi < lo, Return[-1]];
Line 4,018 ⟶ 5,118:
True, mid]
];
]</
'''Iterative'''
<
While[lo <= hi,
mid = lo + Round@((hi - lo)/2);
Line 4,029 ⟶ 5,129:
];
Return[-1];
]</
=={{header|MATLAB}}==
'''Recursive'''
<
if( high < low )
Line 4,052 ⟶ 5,151:
end
end</
Sample Usage:
<
ans =
7</
'''Iterative'''
<
low = 1;
Line 4,079 ⟶ 5,178:
mid = [];
end</
Sample Usage:
<
ans =
7</
=={{header|Maxima}}==
<
if n < L[i] or n > L[j] then 0 else (
while j - i > 0 do (
Line 4,107 ⟶ 5,205:
0
find(a, 421);
82</
=={{header|MAXScript}}==
'''Iterative'''
<
(
lower = 1
Line 4,135 ⟶ 5,232:
arr = #(1, 3, 4, 5, 6, 7, 8, 9, 10)
result = binarySearchIterative arr 6</
'''Recursive'''
<
(
if lower == upper then
Line 4,166 ⟶ 5,263:
arr = #(1, 3, 4, 5, 6, 7, 8, 9, 10)
result = binarySearchRecursive arr 6 1 arr.count</
=={{header|Modula-2}}==
{{trans|C}}
{{works with|ADW Modula-2|any (Compile with the linker option ''Console Application'').}}
<syntaxhighlight lang="modula2">
MODULE BinarySearch;
FROM STextIO IMPORT
WriteLn, WriteString;
FROM SWholeIO IMPORT
WriteInt;
TYPE
TArray = ARRAY [0 .. 9] OF INTEGER;
CONST
A = TArray{-31, 0, 1, 2, 2, 4, 65, 83, 99, 782}; (* Sorted data *)
VAR
X: INTEGER;
PROCEDURE DoBinarySearch(A: ARRAY OF INTEGER; X: INTEGER): INTEGER;
VAR
L, H, M: INTEGER;
BEGIN
L := 0; H := HIGH(A);
WHILE L <= H DO
M := L + (H - L) / 2;
IF A[M] < X THEN
L := M + 1
ELSIF A[M] > X THEN
H := M - 1
ELSE
RETURN M
END
END;
RETURN -1
END DoBinarySearch;
PROCEDURE DoBinarySearchRec(A: ARRAY OF INTEGER; X, L, H: INTEGER): INTEGER;
VAR
M: INTEGER;
BEGIN
IF H < L THEN
RETURN -1
END;
M := L + (H - L) / 2;
IF A[M] > X THEN
RETURN DoBinarySearchRec(A, X, L, M - 1)
ELSIF A[M] < X THEN
RETURN DoBinarySearchRec(A, X, M + 1, H)
ELSE
RETURN M
END
END DoBinarySearchRec;
PROCEDURE WriteResult(X, IndX: INTEGER);
BEGIN
WriteInt(X, 1);
IF IndX >= 0 THEN
WriteString(" is at index ");
WriteInt(IndX, 1);
WriteString(".")
ELSE
WriteString(" is not found.")
END;
WriteLn
END WriteResult;
BEGIN
X := 2;
WriteResult(X, DoBinarySearch(A, X));
X := 5;
WriteResult(X, DoBinarySearchRec(A, X, 0, HIGH(A)));
END BinarySearch.
</syntaxhighlight>
{{out}}
<pre>
2 is at index 4.
5 is not found.
</pre>
=={{header|MiniScript}}==
'''Recursive:'''
<
if high < low then return null
mid = floor((low + high) / 2)
Line 4,176 ⟶ 5,353:
if A[mid] < value then return binarySearch(A, value, mid+1, high)
return mid
end function</
'''Iterative:'''
<
low = 0
high = A.len - 1
Line 4,193 ⟶ 5,370:
end if
end while
end function</
=={{header|N/t/roff}}==
{{works with|GNU TROFF|1.22.2}}
<syntaxhighlight lang="text">.de end
..
.de array
Line 4,236 ⟶ 5,413:
.ie \n[guess]=0 The item \fBdoesn't exist\fP.
.el The item \fBdoes exist\fP.
</syntaxhighlight>
=={{header|Nim}}==
'''Library'''
<
let s = @[2,3,4,5,6,7,8,9,10,12,14,16,18,20,22,25,27,30]
echo binarySearch(s, 10)</
'''Iterative''' (from the standard library)
<
var b = len(a)
while result < b:
Line 4,252 ⟶ 5,428:
if a[mid] < key: result = mid + 1
else: b = mid
if result >= len(a) or a[result] != key: result = -1</
=={{header|Niue}}==
'''Library'''
<
3 bsearch . ( => 2 )
5 bsearch . ( => 0 )
Line 4,265 ⟶ 5,440:
'tom bsearch . ( => 0 )
'kenny bsearch . ( => 2 )
'tony bsearch . ( => -1)</
=={{header|Oberon-2}}==
{{trans|Pascal}}
<syntaxhighlight lang="oberon2">MODULE BS;
IMPORT Out;
VAR
List:ARRAY 10 OF REAL;
PROCEDURE Init(VAR List:ARRAY OF REAL);
BEGIN
List[0] := -31; List[1] := 0; List[2] := 1; List[3] := 2;
List[4] := 2; List[5] := 4; List[6] := 65; List[7] := 83;
List[8] := 99; List[9] := 782;
END Init;
PROCEDURE BinarySearch(List:ARRAY OF REAL;Element:REAL):LONGINT;
VAR
L,M,H:LONGINT;
BEGIN
L := 0;
H := LEN(List)-1;
WHILE L <= H DO
M := (L + H) DIV 2;
IF List[M] > Element THEN
H := M - 1;
ELSIF List[M] < Element THEN
L := M + 1;
ELSE
RETURN M;
END;
END;
RETURN -1;
END BinarySearch;
PROCEDURE RBinarySearch(VAR List:ARRAY OF REAL;Element:REAL;L,R:LONGINT):LONGINT;
VAR
M:LONGINT;
BEGIN
IF R < L THEN RETURN -1 END;
M := (L + R) DIV 2;
IF Element = List[M] THEN
RETURN M
ELSIF Element < List[M] THEN
RETURN RBinarySearch(List, Element, L, R-1)
ELSE
RETURN RBinarySearch(List, Element, M-1, R)
END;
END RBinarySearch;
BEGIN
Init(List);
Out.Int(BinarySearch(List, 2), 0); Out.Ln;
Out.Int(RBinarySearch(List, 65, 0, LEN(List)-1),0); Out.Ln;
END BS.
</syntaxhighlight>
=={{header|Objeck}}==
'''Iterative'''
<
bundle Default {
Line 4,300 ⟶ 5,532:
}
}
}</
=={{header|Objective-C}}==
'''Iterative'''
<
@interface NSArray (BinarySearch)
Line 4,344 ⟶ 5,575:
}
return 0;
}</
'''Recursive'''
<
@interface NSArray (BinarySearchRecursive)
Line 4,383 ⟶ 5,614:
}
return 0;
}</
'''Library'''
{{works with|Mac OS X|10.6+}}
<
int main()
Line 4,400 ⟶ 5,631:
}
return 0;
}</
Using Core Foundation (part of Cocoa, all versions):
<
CFComparisonResult myComparator(const void *x, const void *y, void *context) {
Line 4,420 ⟶ 5,651:
}
return 0;
}</
=={{header|OCaml}}==
'''Recursive'''
<
if high = low then
if a.(low) = value then
Line 4,436 ⟶ 5,666:
binary_search a value (mid + 1) high
else
mid</
Output:
<pre>
Line 4,447 ⟶ 5,677:
</pre>
OCaml supports proper tail-recursion; so this is effectively the same as iteration.
=={{header|Octave}}==
'''Recursive'''
<
if ( high < low )
i = 0;
Line 4,463 ⟶ 5,692:
endif
endif
endfunction</
'''Iterative'''
<
low = 1;
high = numel(array);
Line 4,480 ⟶ 5,709:
endif
endwhile
endfunction</
'''Example of using'''
<
disp(r);
binsearch_r(r, 5, 1, numel(r))
binsearch(r, 5)</
=={{header|Ol}}==
<syntaxhighlight lang="scheme">
(define (binary-search value vector)
(let helper ((low 0)
Line 4,504 ⟶ 5,732:
(binary-search 12 [1 2 3 4 5 6 7 8 9 10 11 12 13]))
; ==> 12
</syntaxhighlight>
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
data = .array~of(1, 3, 5, 7, 9, 11)
-- search keys with a number of edge cases
Line 4,560 ⟶ 5,787:
end
return 0
</syntaxhighlight>
Output:
<pre>
Line 4,579 ⟶ 5,806:
Key 12 not found
</pre>
=={{header|Oz}}==
'''Recursive'''
<
fun {BinarySearch Arr Val}
fun {Search Low High}
Line 4,602 ⟶ 5,828:
in
{System.printInfo "searching 4: "} {Show {BinarySearch A 4}}
{System.printInfo "searching 8: "} {Show {BinarySearch A 8}}</
'''Iterative'''
<
fun {BinarySearch Arr Val}
Low = {NewCell {Array.low Arr}}
Line 4,622 ⟶ 5,848:
in
{System.printInfo "searching 4: "} {Show {BinarySearch A 4}}
{System.printInfo "searching 8: "} {Show {BinarySearch A 8}}</
=={{header|PARI/GP}}==
Note that, despite the name, <code>setsearch</code> works on sorted vectors as well as sets.
<syntaxhighlight lang
The following is another implementation that takes a more manual approach. Instead of using an intrinsic function, a general binary search algorithm is implemented using the language alone.
Line 4,632 ⟶ 5,857:
{{trans|N/t/roff}}
<
local(
minm = 1,
Line 4,655 ⟶ 5,880:
print("Item exists on index ", idx), \
print("Item does not exist anywhere.") \
)</
=={{header|Pascal}}==
'''Iterative'''
<
var
l, m, h: integer;
Line 4,683 ⟶ 5,907:
end;
end;
end;</
Usage:
<
list: array[0 .. 9] of real;
// ...
indexof := binary_search(123, list);</
=={{header|Perl}}==
'''Iterative'''
<
my ($array_ref, $value, $left, $right) = @_;
while ($left <= $right) {
Line 4,707 ⟶ 5,930:
}
return -1;
}</
'''Recursive'''
<
my ($array_ref, $value, $left, $right) = @_;
return -1 if ($right < $left);
Line 4,722 ⟶ 5,945:
binary_search($array_ref, $value, $middle + 1, $right);
}
}</
=={{header|Phix}}==
Standard autoinclude builtin/bsearch.e, reproduced here (for reference only, don't copy/paste unless you plan to modify and rename it)
<!--<
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #7060A8;">binary_search</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">needle</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">haystack</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">lo</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
Line 4,747 ⟶ 5,969:
<span style="color: #008080;">return</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">mid</span> <span style="color: #000080;font-style:italic;">-- where it would go, if inserted now</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</
The low + (high-low)/2 trick is not needed, since interim integer results are accurate to 53 bits (on 32 bit, 64 bits on 64 bit) on Phix.
Returns a positive index if found, otherwise the negative index where it would go if inserted now. Example use
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">binary_search</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- -1</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">binary_search</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- 1</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">binary_search</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- -2</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">binary_search</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- 2</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">binary_search</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- -3</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">binary_search</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- 3</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">binary_search</span><span style="color: #0000FF;">(</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- -4</span>
<!--</syntaxhighlight>-->
=={{header|PHP}}==
'''Iterative'''
<
{
do
Line 4,779 ⟶ 6,003:
return $guess;
}</
'''Recursive'''
<
{
$guess = (int)($start + ( ( $end - $start ) / 2 ));
Line 4,795 ⟶ 6,019:
return $guess;
}</
=={{header|Picat}}==
===Iterative===
<syntaxhighlight lang="picat">go =>
A = [2, 4, 6, 8, 9],
TestValues = [2,1,8,10,9,5],
foreach(Value in TestValues)
test(binary_search,A, Value)
end,
test(binary_search,[1,20,3,4], 5),
nl.
% Test with binary search predicate Search
test(Search,A,Value) =>
Ret = apply(Search,A,Value),
printf("A: %w Value:%d Ret: %d: ", A, Value, Ret),
if Ret == -1 then
println("The array is not sorted.")
elseif Ret == 0 then
printf("The value %d is not in the array.\n", Value)
else
printf("The value %d is found at position %d.\n", Value, Ret)
end.
binary_search(A, Value) = V =>
V1 = 0,
% we want a sorted array
if not sort(A) == A then
V1 := -1
else
Low = 1,
High = A.length,
Mid = 1,
Found = 0,
while (Found == 0, Low <= High)
Mid := (Low + High) // 2,
if A[Mid] > Value then
High := Mid - 1
elseif A[Mid] < Value then
Low := Mid + 1
else
V1 := Mid,
Found := 1
end
end
end,
V = V1.
</syntaxhighlight>
{{out}}
<pre>A: [2,4,6,8,9] Value:2 Ret: 1: The value 2 is found at position 1.
A: [2,4,6,8,9] Value:1 Ret: 0: The value 1 is not in the array.
A: [2,4,6,8,9] Value:8 Ret: 4: The value 8 is found at position 4.
A: [2,4,6,8,9] Value:10 Ret: 0: The value 10 is not in the array.
A: [2,4,6,8,9] Value:9 Ret: 5: The value 9 is found at position 5.
A: [2,4,6,8,9] Value:5 Ret: 0: The value 5 is not in the array.
A: [1,20,3,4] Value:5 Ret: -1: The array is not sorted.
</pre>
===Recursive version===
<syntaxhighlight lang="picat">binary_search_rec(A, Value) = Ret =>
Ret = binary_search_rec(A,Value, 1, A.length).
binary_search_rec(A, _Value, _Low, _High) = -1, sort(A) != A => true.
binary_search_rec(_A, _Value, Low, High) = 0, High < Low => true.
binary_search_rec(A, Value, Low, High) = Mid =>
Mid1 = (Low + High) // 2,
if A[Mid1] > Value then
Mid1 := binary_search_rec(A, Value, Low, Mid1-1)
elseif A[Mid1] < Value then
Mid1 := binary_search_rec(A, Value, Mid1+1, High)
end,
Mid = Mid1.</syntaxhighlight>
=={{header|PicoLisp}}==
'''Recursive'''
<
(unless (=0 Len)
(let (N (inc (/ Len 2)) L (nth Lst N))
Line 4,806 ⟶ 6,102:
((> Val (car L))
(recursiveSearch Val (cdr L) (- Len N)) )
(T (recursiveSearch Val Lst (dec N))) ) ) ) )</
Output:
<pre>: (recursiveSearch 5 (2 3 5 8 "abc" "klm" "xyz" (7) (a b)) 9)
Line 4,815 ⟶ 6,111:
-> NIL</pre>
'''Iterative'''
<
(use (N L)
(loop
Line 4,825 ⟶ 6,121:
(if (> Val (car L))
(setq Lst (cdr L) Len (- Len N))
(setq Len (dec N)) ) ) ) )</
Output:
<pre>: (iterativeSearch 5 (2 3 5 8 "abc" "klm" "xyz" (7) (a b)) 9)
Line 4,833 ⟶ 6,129:
: (iterativeSearch (9) (2 3 5 8 "abc" "klm" "xyz" (7) (a b)) 9)
-> NIL</pre>
=={{header|PL/I}}==
<
search: procedure (A, M) returns (fixed binary);
declare (A(*), M) fixed binary;
Line 4,850 ⟶ 6,145:
end;
return (lbound(A,1)-1);
end search;</
=={{header|Pop11}}==
'''Iterative'''
<
lvars low = 1, high = length(A), mid;
while low <= high do
Line 4,874 ⟶ 6,168:
BinarySearch(A, 4) =>
BinarySearch(A, 5) =>
BinarySearch(A, 8) =></
'''Recursive'''
<
define do_it(low, high);
if high < low then
Line 4,891 ⟶ 6,185:
enddefine;
do_it(1, length(A));
enddefine;</
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function BinarySearch-Iterative ([int[]]$Array, [int]$Value)
{
Line 4,961 ⟶ 6,254:
}
}
</syntaxhighlight>
<syntaxhighlight lang="powershell">
Show-SearchResult -Array 10, 28, 41, 46, 58, 74, 76, 86, 89, 98 -Search 41 -Function Iterative
Show-SearchResult -Array 10, 28, 41, 46, 58, 74, 76, 86, 89, 98 -Search 99 -Function Iterative
Show-SearchResult -Array 10, 28, 41, 46, 58, 74, 76, 86, 89, 98 -Search 86 -Function Recursive
Show-SearchResult -Array 10, 28, 41, 46, 58, 74, 76, 86, 89, 98 -Search 11 -Function Recursive
</syntaxhighlight>
{{Out}}
<pre>
Line 4,975 ⟶ 6,268:
Using BinarySearch-Recursive: 11 not found
</pre>
=={{header|Prolog}}==
Tested with Gnu-Prolog.
<
length(List,N), bin_search_inner(Elt,List,1,N,Result).
Line 5,000 ⟶ 6,292:
MidElt > Elt,
NewEnd is Mid-1,
bin_search_inner(Elt,List,Begin,NewEnd,Result).</
{{out|Output examples}}
Line 5,008 ⟶ 6,300:
?- bin_search(5,[1,2,4,8],Result).
Result = -1.</pre>
=={{header|Python}}==
===Python: Iterative===
<
low = 0
high = len(l)-1
Line 5,121 ⟶ 6,311:
elif l[mid] < value: low = mid+1
else: return mid
return -1</
We can also generalize this kind of binary search from direct matches to searches using a custom comparator function.
In addition to a search for a particular word in an AZ-sorted list, for example, we could also perform a binary search for a word of a given '''length''' (in a word-list sorted by rising length), or for a particular value of any other comparable property of items in a suitably sorted list:
<
def findIndexBinary(p):
def isFound(bounds):
Line 5,216 ⟶ 6,406:
if __name__ == '__main__':
main()
</syntaxhighlight>
{{Out}}
<pre>Word found at index 6
Line 5,222 ⟶ 6,412:
===Python: Recursive===
<
if not l: return -1
if(high == -1): high = len(l)-1
Line 5,231 ⟶ 6,421:
if l[mid] > value: return binary_search(l, value, low, mid-1)
elif l[mid] < value: return binary_search(l, value, mid+1, high)
else: return mid</
Generalizing again with a custom comparator function (see preamble to second iterative version above).
Line 5,237 ⟶ 6,427:
This time using the recursive definition:
<
def findIndexBinary_(p):
def go(xs):
Line 5,304 ⟶ 6,494:
'Word of given length found at index ' + str(mb2)
)
)</
{{Out}}
<pre>Word found at index 9
Line 5,311 ⟶ 6,501:
===Python: Library===
<br>Python's <code>bisect</code> module provides binary search functions
<
index = bisect.bisect_right(list, item) # rightmost insertion point
index = bisect.bisect(list, item) # same as bisect_right
Line 5,318 ⟶ 6,508:
bisect.insort_left(list, item)
bisect.insort_right(list, item)
bisect.insort(list, item)</
====Python: Alternate====
Complete binary search function with python's <code>bisect</code> module:
<
def binary_search(a, x, lo=0, hi=None): # can't use a to specify default for hi
hi = hi if hi is not None else len(a) # hi defaults to len(a)
pos = bisect_left(a,x,lo,hi) # find insertion position
return (pos if pos != hi and a[pos] == x else -1) # don't walk off the end</
===Python: Approximate binary search===
Returns the nearest item of list l to value.
<
low = 0
high = len(l)-1
Line 5,343 ⟶ 6,533:
else:
return mid
return high if abs(l[high] - value) < abs(l[low] - value) else low</
=={{header|Quackery}}==
Written from pseudocode for rightmost insertion point, iterative.
<syntaxhighlight lang="quackery"> [ stack ] is value.bs ( --> n )
[ stack ] is nest.bs ( --> n )
[ stack ] is test.bs ( --> n )
[ ]'[ test.bs put
value.bs put
nest.bs put
1 - swap
[ 2dup < if done
2dup + 1 >>
nest.bs share over peek
value.bs share swap
test.bs share do iff
[ 1 - unrot nip ]
again
[ 1+ nip ] again ]
drop
nest.bs take over peek
value.bs take 2dup swap
test.bs share do
dip [ test.bs take do ]
or not
dup dip [ not + ] ] is bsearchwith ( n n [ x --> n b )
[ dup echo
over size 0 swap 2swap
bsearchwith < iff
[ say " was identified as item " ]
else
[ say " could go into position " ]
echo
say "." cr ] is task ( [ n --> n )</syntaxhighlight>
{{out}}
Testing in the shell.
<pre>/O> ' [ 10 20 30 40 50 60 70 80 90 ] 30 task
... ' [ 10 20 30 40 50 60 70 80 90 ] 66 task
...
30 was identified as item 2.
66 could go into position 6.
Stack empty.</pre>
=={{header|R}}==
'''Recursive'''
<
if ( high < low ) {
return(NULL)
Line 5,359 ⟶ 6,595:
mid
}
}</
'''Iterative'''
<
low = 1
high = length(A)
Line 5,375 ⟶ 6,611:
}
NULL
}</
'''Example'''
<
IterBinSearch(a, 50)
BinSearch(a, 50, 1, length(a)) # output 50
IterBinSearch(a, 101) # outputs NULL</
=={{header|Racket}}==
<
#lang racket
(define (binary-search x v)
Line 5,397 ⟶ 6,632:
[else m])]))
(loop 0 (vector-length v)))
</syntaxhighlight>
Examples:
<pre>
Line 5,403 ⟶ 6,638:
(binary-search 6 #(1 3 4 5 7 8 9 10)) ; gives #f
</pre>
=={{header|Raku}}==
(formerly Perl 6)
With either of the below implementations of <code>binary_search</code>, one could write a function to search any object that does <code>Positional</code> this way:
<syntaxhighlight lang="raku"
binary_search { $x cmp @a[$^i] }, 0, @a.end
}</
'''Iterative'''
{{works with|Rakudo|2015.12}}
<syntaxhighlight lang="raku"
until $lo > $hi {
my Int $mid = ($lo + $hi) div 2;
Line 5,422 ⟶ 6,656:
}
fail;
}</
'''Recursive'''
{{trans|Haskell}}
{{works with|Rakudo|2015.12}}
<syntaxhighlight lang="raku"
$lo <= $hi or fail;
my Int $mid = ($lo + $hi) div 2;
Line 5,434 ⟶ 6,668:
default { $mid }
}
}</
=={{header|REXX}}==
Line 5,440 ⟶ 6,674:
Incidentally, REXX doesn't care if the values in the list are integers (or even numbers), as long as they're in order.
<br><br>(includes the extra credit)
<syntaxhighlight lang="rexx"></syntaxhighlight>
/*REXX program finds a value in a list of integers using an iterative binary search.*/
list=3 7
449 463 467 491 503 509 523 547 571 577 601 619 643 647 661 677 683 691 709,
743 761 773 797 811 823 829 839 859 863 883 887 911 919 941 953 971 983 1013
If needle=='' Then
Call exit '***error*** no argument specified.'
low=1
high=words(list)
loc=binarysearch(low,high)
If loc==-1 Then
Call exit needle "wasn't found in the list."
Say needle "is in the list, its index is:" loc'.'
Exit
/*---------------------------------------------------------------------*/
binarysearch: Procedure Expose list needle
Parse Arg i_low,i_high
If i_high<i_low Then /* the item wasn't found in the list */
Return-1
i_mid=(i_low+i_high)%2 /* calculate the midpoint in the list */
y=word(list,i_mid) /* obtain the midpoint value in the list */
Select
When y=needle Then
Return i_mid
When y>needle Then
Return binarysearch(i_low,i_mid-1)
Otherwise
Return binarysearch(i_mid+1,i_high)
End
exit: Say arg(1)
{{out|output|text= when using the input of: <tt> 499.1 </tt>}}
<pre>499.1 wasn't found in the list.</pre>
{{out|output|text= when using the input of: <tt> 619 </tt>}}
<pre>619 is in the list, its index is: 53.</pre>
===iterative version===
(includes the extra credit)
<syntaxhighlight lang="rexx">/* REXX program finds a value in a list of integers */
/* using an iterative binary search. */
list=3 7 13 19 23 31 43 47 61 73 83 89 103 109 113 131 139 151 167 181 193 199,
229 233 241 271 283 293 313 317 337 349 353 359 383 389 401 409 421 433 443,
449 463 467 491 503 509 523 547 571 577 601 619 643 647 661 677 683 691 709,
743 761 773 797 811 823 829 839 859 863 883 887 911 919 941 953 971 983 1013
/* list: a list of some low weak primes. */
Parse Arg needle /* get a number to be looked for */
If needle=="" Then
Call exit "***error*** no argument specified."
low=1
high=words(list)
Do While low<=high
mid=(low+high)%2
y=word(list,mid)
Select
When y=needle Then
Call exit needle "is in the list, its index is:" mid'.'
When y>needle Then /* too high */
high=mid-1 /* set upper nound */
Otherwise /* too low */
low=mid+1 /* set lower limit */
End
End
Call exit needle "wasn't found in the list."
exit: Say arg(1) </syntaxhighlight>
{{out|output|text= when using the input of: <tt> -314 </tt>}}
<pre>-314 wasn't found in the list.
</pre>
{{out|output|text= when using the input of: <tt> 619 </tt>}}
<pre>619 is in the list, its index is: 53.</pre>
===iterative version===
(includes the extra credit)
<
@= 3 7 13 19 23 31 43 47 61 73 83 89 103 109 113 131 139 151 167 181,
193 199 229 233 241 271 283 293 313 317 337 349 353 359 383 389 401 409 421 433,
Line 5,507 ⟶ 6,773:
end /*while*/
say ? " wasn't found in the list." /*stick a fork in it, we're all done. */</
{{out|output|text= when using the input of: <tt> -314 </tt>}}
<pre>
Line 5,520 ⟶ 6,786:
619 is in the list, its index is: 53
</pre>
=={{header|Ring}}==
<
decimals(0)
array = [7, 14, 21, 28, 35, 42, 49, 56, 63, 70]
Line 5,553 ⟶ 6,818:
return -1
ok
</syntaxhighlight>
Output:
<pre>
the value 42 was found at index 6
</pre>
=={{header|Ruby}}==
'''Recursive'''
<
def binary_search(val, low=0, high=(length - 1))
return nil if high < low
Line 5,584 ⟶ 6,848:
puts "#{val} not found in array"
end
end</
'''Iterative'''
<
def binary_search_iterative(val)
low, high = 0, length - 1
Line 5,613 ⟶ 6,877:
puts "#{val} not found in array"
end
end</
{{out}}
<pre>
Line 5,624 ⟶ 6,888:
'''Built in'''
Since Ruby 2.0, arrays ship with a binary search method "bsearch":
<
needles = [0,42,45,24324,99999]
needles.select{|needle| haystack.bsearch{|hay| needle <=> hay} } # => [0, 45, 24324]
</
=={{header|Rust}}==
'''Iterative'''
<syntaxhighlight lang="rust">fn binary_search<T:PartialOrd>(v: &[T], searchvalue: T) -> Option<T> {
let mut lower = 0 as usize;
let mut upper = v.len() - 1;
Line 5,662 ⟶ 6,903:
let mid = (upper + lower) / 2;
if v[mid] == searchvalue {
return
} else if searchvalue < v[mid] {
upper = mid - 1;
Line 5,670 ⟶ 6,911:
}
}</
=={{header|Scala}}==
'''Recursive'''
<
def recurse(low: Int, high: Int): Option[Int] = (low + high) / 2 match {
case _ if high < low => None
Line 5,683 ⟶ 6,923:
}
recurse(0, a.size - 1)
}</
'''Iterative'''
<
var low: Int = 0
var high: Int = xs.size - 1
Line 5,696 ⟶ 6,936:
}
None //not found
}</
'''Test'''
<
val odds = 1 to n by 2
val result = (0 to n).flatMap(binarySearch(odds, _))
Line 5,707 ⟶ 6,947:
}
def main() = testBinarySearch(12)</
Output:
<pre>Range(1, 3, 5, 7, 9, 11) are odd natural numbers
Line 5,716 ⟶ 6,956:
4 is ordinal of 9
5 is ordinal of 11</pre>
=={{header|Scheme}}==
'''Recursive'''
<
(let helper ((low 0)
(high (- (vector-length vector) 1)))
Line 5,729 ⟶ 6,968:
((< (vector-ref vector middle) value)
(helper (+ middle 1) high))
(else middle))))))</
Example:
<pre>
Line 5,739 ⟶ 6,978:
The calls to helper are in tail position, so since Scheme implementations
support proper tail-recursion the computation proces is iterative.
=={{header|Seed7}}==
'''Iterative'''
<
result
var integer: result is 0;
Line 5,761 ⟶ 6,999:
end if;
end while;
end func;</
'''Recursive'''
<
result
var integer: result is 0;
Line 5,778 ⟶ 7,016:
const func integer: binarySearchRecursive (in array elemType: arr, in elemType: aKey) is
return binarySearch(arr, aKey, 1, length(arr));</
=={{header|SequenceL}}==
'''Recursive'''
<
let
mid := low + (high - low) / 2;
Line 5,792 ⟶ 7,029:
binarySearch(A, value, mid + 1, high) when A[mid] < value
else
mid;</
=={{header|Sidef}}==
Iterative:
<
var l = 0
Line 5,809 ⟶ 7,045:
return -1
}</
Recursive:
<
high < low && return -1
var middle = ((high+low) // 2)
Line 5,826 ⟶ 7,062:
}
}
}</
Usage:
<
=={{header|Simula}}==
<
Line 5,919 ⟶ 7,154:
END;
END</
{{out}}
<pre>
Line 5,949 ⟶ 7,184:
</pre>
=={{header|SPARK}}==
SPARK does not allow recursion, so only the iterative solution is provided. This example shows the use of a loop assertion.
Line 5,960 ⟶ 7,194:
The first version has a postcondition that if Found is True the Position value returned is correct. This version also has a number of 'check' annotations. These are inserted to allow the Simplifier to prove all the verification conditions. See [[SPARK_Proof_Process|the SPARK Proof Process]].
<
subtype Item_Type is Integer; -- From specs.
Line 6,056 ⟶ 7,290:
end Search;
end Binary_Searches;</
The second version of the package has a stronger postcondition on Search, which also states that if Found is False then there is no value in Source equal to Item. This postcondition cannot be proved without a precondition that Source is ordered. This version needs four user rules (see [[SPARK_Proof_Process|the SPARK Proof Process]]) to be provided to the Simplifier so that it can prove all the verification conditions.
<
subtype Item_Type is Integer; -- From specs.
Line 6,147 ⟶ 7,381:
end Search;
end Binary_Searches;</
The user rules for this version of the package (written in FDL, a language for modelling algorithms).
<pre>binary_search_rule(1): (X + Y) div 2 >= X
Line 6,180 ⟶ 7,414:
</pre>
The test program:
<
with SPARK_IO;
Line 6,264 ⟶ 7,498:
Run_Search (Source => Array_Type9'(1, 2, 3, 4, 5, 6, 7, 8, 9), Item => 6);
end Test_Binary_Search;
</syntaxhighlight>
Test output (for the last three tests the array is indexed from 91):
Line 6,276 ⟶ 7,510:
Searching for 6 in ( 1 2 3 4 5 6 7 8 9): found as #96.
</pre>
=={{header|Standard ML}}==
'''Recursive'''
<
let
fun aux slice =
Line 6,295 ⟶ 7,528:
in
aux (ArraySlice.full arr)
end</
Usage:
<pre>
Line 6,334 ⟶ 7,567:
val it = SOME (4,8) : (int * IntArray.elem) option
</pre>
=={{header|Swift}}==
'''Recursive'''
<
var recurse: ((Int, Int) -> Int?)!
recurse = {(low, high) in switch (low + high) / 2 {
Line 6,346 ⟶ 7,578:
}}
return recurse(0, xs.count - 1)
}</
'''Iterative'''
<
var (low, high) = (0, xs.count - 1)
while low <= high {
Line 6,358 ⟶ 7,590:
}
return nil
}</
'''Test'''
<
let odds = Array(stride(from: 1, through: n, by: 2))
let result = flatMap(0...n) {binarySearch(odds, $0)}
Line 6,374 ⟶ 7,606:
func flatMap<T, U>(source: [T], transform: (T) -> U?) -> [U] {
return source.reduce([]) {(var xs, x) in if let x = transform(x) {xs.append(x)}; return xs}
}</
Output:
<pre>[1, 3, 5, 7, 9, 11] are odd natural numbers
Line 6,383 ⟶ 7,615:
4 is ordinal of 9
5 is ordinal of 11</pre>
=={{header|Symsyn}}==
<
a : 1 : 2 : 27 : 44 : 46 : 57 : 77 : 154 : 212
Line 6,417 ⟶ 7,647:
"'result = ' R" []
</syntaxhighlight>
=={{header|Tcl}}==
ref: [http://wiki.tcl.tk/22796 Tcl wiki]
<
set len [llength $lst]
if {$len == 0} {
Line 6,445 ⟶ 7,674:
puts "element $x found at index $idx"
}
}</
Note also that, from Tcl 8.4 onwards, the <tt>lsearch</tt> command includes the <tt>-sorted</tt> option to enable binary searching of Tcl lists.
<
set idx [lsearch -sorted -exact $lst $x]
if {$idx == -1} {
Line 6,454 ⟶ 7,683:
puts "element $x found at index $idx"
}
}</
=={{header|UNIX Shell}}==
Line 6,512 ⟶ 7,689:
'''Reading values line by line'''
<
#!/bin/ksh
# This should work on any clone of Bourne Shell, ksh is the fastest.
Line 6,524 ⟶ 7,701:
array[${#array[*]}]=$line
done
</syntaxhighlight>
'''Iterative'''
<
left=0
right=$(($size - 1))
Line 6,544 ⟶ 7,721:
done
echo 'ERROR 404 : NOT FOUND'
</syntaxhighlight>
'''Recursive'''
<syntaxhighlight lang="text"> No code yet </
=={{header|UnixPipes}}==
'''Parallel'''
<
a=$1; s=$2; l=$3; r=$4;
mid=$(expr ${#a[*]} / 2);
Line 6,568 ⟶ 7,744:
}
echo "1 2 3 4 6 7 8 9" | binsearch 6</
=={{header|Vedit macro language}}==
Line 6,688 ⟶ 7,751:
For this implementation, the numbers to be searched must be stored in current edit buffer, one number per line.
(Could be for example a csv table where the first column is used as key field.)
<
#3 = Get_Num("Value to search: ")
EOF
Line 6,717 ⟶ 7,780:
}
}
return(0) // not found</
=={{header|
<syntaxhighlight lang="v (vlang)">fn binary_search_rec(a []f64, value f64, low int, high int) int { // recursive
if high <= low {
}
if a[mid] > value {
return binary_search_rec(a, value, low, mid-1)
} else if a[mid] < value {
return binary_search_rec(a, value, mid+1, high)
}
return mid
}
fn binary_search_it(a []f64, value f64) int { //iterative
mut low := 0
mut high := a.len - 1
for low <= high {
mid := (low + high) / 2
if a[mid] > value {
high = mid - 1
} else if a[mid] < value {
low = mid + 1
} else {
return mid
}
}
return -1
}
fn main() {
f_list := [1.2,1.5,2,5,5.13,5.4,5.89,9,10]
println(binary_search_rec(f_list,9,0,f_list.len))
println(binary_search_rec(f_list,15,0,f_list.len))
println(binary_search_it(f_list,9))
println(binary_search_it(f_list,15))
}</syntaxhighlight>
{{out}}
<pre>
7
-1
7
-1
</pre>
=={{header|Wortel}}==
{{trans|JavaScript}}
<
@var rec &[a v l h] [
@if < h l @return null
Line 6,783 ⟶ 7,852:
]
null
]</
=={{header|Wren}}==
<
static recursive(a, value, low, high) {
if (high < low) return -1
Line 6,833 ⟶ 7,901:
System.print(" %(value) was not found in the array.")
}
}</
{{out}}
Line 6,848 ⟶ 7,916:
</pre>
=={{header|
{{trans|
{{works with|EXPL-32}}
<syntaxhighlight lang="xpl0">
\Binary search
code CrLf=9, IntOut=11, Text=12;
def Size = 10;
integer A, X, I;
function integer DoBinarySearch(A, N, X);
integer
integer L, H, M;
begin
L:= 0; H:= N - 1;
while L <= H do
begin
M:= L + (H - L) / 2;
case of
A(M) < X: L:= M + 1;
A(M) > X: H:= M - 1
other return M;
end;
return -1;
end;
function integer DoBinarySearchRec(A, X, L, H);
integer A, X, L, H;
integer M;
begin
if
return -1;
M:= L + (H - L)
case of
A(M) > X: return DoBinarySearchRec(A, X, L, M - 1);
A(M) < X: return DoBinarySearchRec(A, X, M + 1, H)
end;
procedure PrintResult(X, IndX);
integer X, IndX;
begin
IntOut(0, X);
if IndX >= 0 then
begin
Text(0, " is at index ");
IntOut(0, IndX);
Text(0, ".")
end
else
Text(0, " is not found.");
CrLf(0)
end;
begin
\Sorted data
A:= [-31, 0, 1, 2, 2, 4, 65, 83, 99, 782];
X:= 2;
I:= DoBinarySearch(A, Size, X);
PrintResult(X, I);
X:= 5;
I:= DoBinarySearchRec(A, X, 0, Size - 1);
PrintResult(X, I);
end
</syntaxhighlight>
{{out}}
<pre>
2 is at index 4.
5 is not found.
</pre>
=={{header|z/Arch Assembler}}==
This optimized version for z/Arch, uses six general regs and avoid branch misspredictions for high/low cases.
<
BINSRCH LA R5,TABLE Begin of table
SR R2,R2 low = 0
Line 6,901 ⟶ 8,004:
LOCRH R3,R0 High? => HIGH = MID-1
LOCRL R2,R1 Low? => LOW = MID+1
J LOOP }</
=={{header|Zig}}==
'''Works with:''' 0.11.x, 0.12.0-dev.1381+61861ef39
For 0.10.x, replace @intFromPtr(...) with @ptrToInt(...) in these examples.
===With slices===
====Iterative====
<syntaxhighlight lang="zig">pub fn binarySearch(comptime T: type, input: []const T, search_value: T) ?usize {
if (input.len == 0) return null;
if (@sizeOf(T) == 0) return 0;
var view: []const T = input;
const item_ptr: *const T = item_ptr: while (view.len > 0) {
const mid = (view.len - 1) / 2;
const mid_elem_ptr: *const T = &view[mid];
if (mid_elem_ptr.* > search_value)
view = view[0..mid]
else if (mid_elem_ptr.* < search_value)
view = view[mid + 1 .. view.len]
else
break :item_ptr mid_elem_ptr;
} else return null;
const distance_in_bytes = @intFromPtr(item_ptr) - @intFromPtr(input.ptr);
return (distance_in_bytes / @sizeOf(T));
}</syntaxhighlight>
====Recursive====
<syntaxhighlight lang="zig">pub fn binarySearch(comptime T: type, input: []const T, search_value: T) ?usize {
return binarySearchInner(T, input, search_value, @intFromPtr(input.ptr));
}
fn binarySearchInner(comptime T: type, input: []const T, search_value: T, start_address: usize) ?usize {
if (input.len == 0) return null;
if (@sizeOf(T) == 0) return 0;
const mid = (input.len - 1) / 2;
const mid_elem_ptr: *const T = &input[mid];
return if (mid_elem_ptr.* > search_value)
binarySearchInner(T, input[0..mid], search_value, start_address)
else if (mid_elem_ptr.* < search_value)
binarySearchInner(T, input[mid + 1 .. input.len], search_value, start_address)
else
(@intFromPtr(mid_elem_ptr) - start_address) / @sizeOf(T);
}</syntaxhighlight>
===With indexes===
====Iterative====
<syntaxhighlight lang="zig">const math = @import("std").math;
pub fn binarySearch(comptime T: type, input: []const T, search_value: T) ?usize {
if (input.len == 0) return null;
if (@sizeOf(T) == 0) return 0;
var low: usize = 0;
var high: usize = input.len - 1;
return while (low <= high) {
const mid = ((high - low) / 2) + low;
const mid_elem: T = input[mid];
if (mid_elem > search_value)
high = math.sub(usize, mid, 1) catch break null
else if (mid_elem < search_value)
low = mid + 1
else
break mid;
} else null;
}</syntaxhighlight>
====Recursive====
<syntaxhighlight lang="zig">const math = @import("std").math;
pub fn binarySearch(comptime T: type, input: []const T, search_value: T) ?usize {
if (input.len == 0) return null;
if (@sizeOf(T) == 0) return 0;
return binarySearchInner(T, input, search_value, 0, input.len - 1);
}
fn binarySearchInner(comptime T: type, input: []const T, search_value: T, low: usize, high: usize) ?usize {
if (low > high) return null;
const mid = ((high - low) / 2) + low;
const mid_elem: T = input[mid];
return if (mid_elem > search_value)
binarySearchInner(T, input, search_value, low, math.sub(usize, mid, 1) catch return null)
else if (mid_elem < search_value)
binarySearchInner(T, input, search_value, mid + 1, high)
else
mid;
}</syntaxhighlight>
=={{header|zkl}}==
This algorithm is tail recursive, which means it is both recursive and iterative (since tail recursion optimizes to a jump). Overflow is not possible because Ints (64 bit) are a lot bigger than the max length of a list.
<
fcn(list,value, low,high){
if (high < low) return(Void); // not found
Line 6,913 ⟶ 8,113:
return(mid); // found
}(list,value,0,list.len()-1);
}</
<
foreach i in ([0..12]){
n:=bsearch(list,i);
if (Void==n) println("Not found: ",i);
else println("found ",i," at index ",n);
}</
{{out}}
<pre>
Line 6,937 ⟶ 8,137:
Not found: 12
</pre>
|