实现拥有重复元素的二分查找法

本文详细介绍了二分查找法在Python中的实现过程,并通过一系列测试案例验证了其正确性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

github 莫名其妙的打不开了,那就贴在这里吧


#!/usr/bin/env python
# -*- #coding:utf-8
'''
Created on 2013-9-4

@author: mingdong.li

二分查找法,有相同元素列表
'''
import unittest
from test.test_bisect import TestErrorHandling
from test import test_support

_searchMode = {"FIRST":1, "LAST":0}

def binarySearchTemplate(sequence, fromIndex, toIndex, key, searchMode):
    """
    @param sequence: is a list or tuple to be searched, it's sequential and no repeating elements
    @param fromIndex: the index of the first element to be searched
    @param toIndex: the index of the last element to be searched
    @param key: the value to be searched for
    @param searchMode: FIRST=1(return the index of the first element in the repeating sequence); LAST=0(the last one) 
    @return: index of the search key, no found will return -1
    """
    low = fromIndex
    high = toIndex - 1
    flag = -1
    while(low <= high):
        mid = low + ((high-low)>>1)
        midValue = sequence[mid]
        if midValue < key:
            low = mid + 1
        elif midValue > key:
            high = mid -1
        else:
            if searchMode is None:
                return mid
            elif searchMode == _searchMode['FIRST']:
                high = mid - 1
                flag = mid
            elif searchMode == _searchMode['LAST']:
                low = mid + 1
                flag = mid
    else:
        if searchMode == _searchMode['FIRST']:
            if key == sequence[high]:
#                print 'first high'
                return high
            else:
#                print 'first flag'
                return flag
        elif searchMode == _searchMode['LAST']:
            if key == sequence[low-1]:
#                print 'last high'
                return low-1
            else:
#                print 'last flag'
                return flag
        else:
            return -1
#        return -1

def binarySearch(sequence, key, searchMode=None):
    if not isinstance(sequence, list) and not isinstance(sequence, tuple):
        return "The %s is not list or tuple" % sequence
    return binarySearchTemplate(sequence, 0, len(sequence), key, searchMode) 

def test_main(verbose=None):
    
    class TestBinarySearch(unittest.TestCase):
        a = [1, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 7, 7, 7, 7, 7]
        b = (1, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 7, 7)
        precomputedCase = [
            (binarySearch, 'a', 88, None, "The a is not list or tuple"),
            (binarySearch, a, 2, None, 3),
            (binarySearch, a, 88, None, -1),
            (binarySearch, a, 7, _searchMode['FIRST'], 11),
            (binarySearch, a, 7, _searchMode['LAST'], 15),
            (binarySearch, a, 1, _searchMode['FIRST'], 0),
            (binarySearch, a, 1, _searchMode['LAST'], 2),
            (binarySearch, a, 4, _searchMode['FIRST'], 6),
            (binarySearch, a, 11, _searchMode['FIRST'], -1),
            (binarySearch, a, 11, _searchMode['LAST'], -1),
            
            (binarySearch, b, 2, None, 4),
            (binarySearch, b, 88, None, -1),
            (binarySearch, b, 7, _searchMode['FIRST'], 11),
            (binarySearch, b, 7, _searchMode['LAST'], 12),
            (binarySearch, b, 1, _searchMode['FIRST'], 0),
            (binarySearch, b, 1, _searchMode['LAST'], 2),
            (binarySearch, b, 4, _searchMode['FIRST'], 6),
            (binarySearch, b, 11, _searchMode['FIRST'], -1),
            (binarySearch, b, 11, _searchMode['LAST'], -1)
        ]
        
        def test_precomputed(self):
            for func, sequ, key, mode, expected in self.precomputedCase:
                self.assertEqual(func(sequ, key, mode), expected)

    from types import BuiltinFunctionType
    test_classes = [TestBinarySearch]
    if isinstance(binarySearch, BuiltinFunctionType):
        test_classes.append(TestErrorHandling)
    
    test_support.run_unittest(*test_classes)

if __name__ == '__main__':
    print "test..."
    test_main(verbose=True)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值