Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 这种递归二进制搜索算法能更有效吗?_Python_Algorithm_Recursion_Binary Search - Fatal编程技术网

Python 这种递归二进制搜索算法能更有效吗?

Python 这种递归二进制搜索算法能更有效吗?,python,algorithm,recursion,binary-search,Python,Algorithm,Recursion,Binary Search,我见过很多不同的算法实现,但我想知道除了让搜索变成二进制外,是否还有其他方法可以提高效率。我设计了这个特定版本的算法,因此数组/列表的边和中点将立即检查正在搜索的键,以避免在搜索的键只是第一个、中间或最后一个元素时循环搜索 def searchRB(the_array, the_key, imin, imax): print("searching") found = False if (0 > the_key or the_key > len(the_arra

我见过很多不同的算法实现,但我想知道除了让搜索变成二进制外,是否还有其他方法可以提高效率。我设计了这个特定版本的算法,因此数组/列表的边和中点将立即检查正在搜索的键,以避免在搜索的键只是第一个、中间或最后一个元素时循环搜索

def searchRB(the_array, the_key, imin, imax):
    print("searching")
    found = False
    if (0 > the_key or the_key > len(the_array)):
        return found
    else:
        imid = imin + ((imax - imin) // 2)
        if imid == the_key or imin == the_key or imax == the_key:
            found = True
            return found
        elif the_array[imid] > the_key:
            return searchRB(the_array, the_key, imin, imid-1)
        elif the_array[imid] < the_key:
            return searchRB(the_array, the_key, imid+1, imax)
        else:
            return found
def searchRB(_数组、_键、imin、imax):
打印(“搜索”)
发现=错误
如果(0>_键或_键>len(_数组)):
返回发现
其他:
imid=imin+((imax-imin)//2)
如果imid==_键或imin==_键或imax==_键:
找到=真
返回发现
elif_数组[imid]>_键:
返回searchRB(_数组、_键、imin、imid-1)
elif_数组[imid]<_键:
返回searchRB(_数组、_键、imid+1、imax)
其他:
返回发现
例如,如果您正在查找1-100列表中的数字1,则与其他一些实现不同,这将在第一个循环中找到它

但是,我不确定这是否真的提高了效率(除了某些边缘情况),如果继续循环并且每次都必须检查这三个值,那么检查列表/数组中的第一个、中间和结束值是否真的有害


这是这种算法的好的还是坏的实现,还是我只是在吹毛求疵?

主要的一个大问题是从递归方法改为使用while循环,从而节省了调用堆栈(因为python没有尾部递归)

您有可以优化的小冗余。 算法已经进行了充分优化,除非您了解编译器,否则不要使用

如果你沿着左边的树往下走,你会一遍又一遍地比较同一个imin,但是这整条线可能是并行的,也可能是顺序的

如果_数组[imid]==_键或_数组[min]==_键或_数组[imax]==_键:

此外,这可能会影响缓存性能,因为您将始终将_数组[min]保留在缓存中。有时编译器会在缓存中尝试访问的索引周围存储数组中的块。 您可能会浪费比仅为该1值更多的缓存

这样的语句也可以进行优化,您可以只键入returntrue,但这应该由编译器来处理

found=True
找到返回值

没有找到
作为对象将优化代码,因为该对象不会一直存储在内存中

这个else语句似乎是多余的,因为没有其他可能的方法
else
找到返回值

实际的相关优化将来自对数据集的更多了解


如果您能够预处理数据(或获得更多有关数据的信息),您可以使用其他算法。

迭代二进制搜索将更有效。有趣的是,您能否详细说明一下原因?您将如何开始搜索?_key,imin,imax的值是什么?_key=您正在搜索的数字,imin=您搜索范围内的最小值,imax=您搜索范围内的最大值。因为迭代实现避免了更多函数调用的开销,而在Python中,这些调用的速度并不是非常快。我认为这是在吹毛求疵,是的:渐进地(随着_数组的大小越来越大),快速识别端点并没有什么好处。与元素的数量相比,可能的端点的数量非常少,因此您在检查罕见情况的平均元素上浪费了额外的时间。另外,
found
变量也没有用:只需返回
False
True
False
(分别),现在返回
found
,并删除两行
found=
。我注意到,在这里搜索与键等价的最小值和最大值效果不太好。正如您所说,我的方法只是在每次循环时比较相同的最小值和最大值(这是无用的),但是如果您使用
the_key==the_array[imin]或the_key==the_array[imax]
,则索引超出范围。我认为最好完全放弃它,只比较关键点和中点。是的,只比较中点,而且我认为你关于何时打破的逻辑有点不正确,它应该比较mid和0以及数组的长度,以确定索引是否在bound范围内。应该在函数的开头定义
imid
,并且该语句应该是
if 0>imid或imid>len(数组):
,如您所说。