使用递归实现二进制搜索功能

时间:2019-05-15 06:14:06

标签: python search

我试图递归地编写二进制搜索函数,而不使用切片进行作业,但是当我运行单元测试时,出现一个错误,提示我的函数实际上没有执行二进制搜索。

这是我的代码。我得到了def binarySearchRec(alist,item,first = None,last = None),所以我必须使用这4个参数,且默认的first和last值设置为none。

def binarySearchRec(alist, item, first=None, last=None):
    if first == None and last == None:
        return binarySearchRec(alist, item, 0, len(alist) - 1)
    elif item < alist[first] or item > alist[last]:
        return False
    else:
        midpoint = (first + last) // 2
        if item < alist[midpoint]:
            return binarySearchRec(alist, item, first, midpoint - 1)
        elif item > alist[midpoint]:
            return binarySearchRec(alist, item, midpoint + 1, last)
        else:
            return True

现在,当我运行单元测试时,出现一条错误消息:

FAIL: test_ensureBinarySearch (__main__.TestProblem2)
P2: Is binarySearchRec actually performing a binary search?
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/Shared/Homework4/hw4_test.py", line 23, in test
    return func(*args, **kwargs)
  File "/Users/Shared/Homework4/hw4_test.py", line 193, in 
test_ensureBinarySearch
    self.assertLess(items.accesses, 20, "Binary search should only be 
testing log_2(N) items in a list with N items")
AssertionError: 32 not less than 20 : Binary search should only be testing 
log_2(N) items in a list with N items

我假设它与访问次数有关?不确定“访问”是什么意思。有人可以查看我的代码并告诉我我做错了什么吗?谢谢!

这是我失败的单元测试的代码:

 def test_ensureBinarySearch(self):
        '''P2: Is binarySearchRec actually performing a binary search?'''
        items = StrictList(range(512))
        self.assertTrue(binarySearchRec(items, 232), "Failed to find an element 
in the list")
        self.assertLess(items.accesses, 20, "Binary search should only be 
testing log_2(N) items in a list with N items")

1 个答案:

答案 0 :(得分:0)

每个循环中,您两次访问items(您的alist)以检查是否elif item < alist[first] or item > alist[last]:。如果items[midpoint]不是<item,您还将检查alist[midpoint]两次。

您可以放弃检查elif item < alist[first] or item > alist[last]:,而只是测试firstlast是否超出限制。 更新您还可以使用临时值mid_value = alist[midpoint]来减少对alist[midpoint]的访问次数。

您可以放置​​elif item > alist[midpoint]:和第三块。只有一个else可以正常工作。

它不会包含您所包含的优化,但是会减少对items的访问次数。

最后,如果first和last是None,只需将其设置为正确的值并继续。无需重新调用功能。