这里有具体的讨论,并配有C的代码,https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/25.0.md 。二分查找有对数的复杂度,C++的标准库中也实现了binary-search,具体的原理这里就不说了,下面就谈谈算法的Scheme实现:
#!/usr/bin/guile -s
!#
(define (binary-search lst val)
(define (helper left right)
(if (> left right) (display "no value")
(let* ((idx (quotient (+ left right 1) 2))
(mid (list-ref lst idx)))
(cond ((= mid val) (display idx))
((> mid val) (helper left (- idx 1)))
((< mid val) (helper (+ idx 1) right))))))
(helper 0 (- (length lst) 1)))
开头的两行是脚本语言中特有的,指定了执行脚本的程序,在主程序binary-search中内嵌了一个函数,首先判断一下程序终止的条件,即当我们传递的参数中左下标都已经大于右下标还没有找到时就说明val是不在序列中的,然后定义两个局部变量方便程序书写,在cond中选择程序的执行路径,若此次没有找到那么就递归的执行算法。这里思路是和函数式编程的思想是一致的。
这里注意let*的用法,因为mid的取值需要依赖idx,所以这里如果用let编译器将会报错,抱怨idx是一个没有约束的变量。