이진 검색 이진 검색

이진 검색 이진 검색

이진 검색 알고리즘

이진 검색 (이진 검색) 방법은 명령 세트의 지정된 키를 찾을 수있는 방법입니다. 소규모에서 대규모까지의 순서에 따라 수집의 핵심 요소들의 세트가 가정하자. 수집의 핵심 요소들의리스트 일 수있다 (\리스트 = (X_1, X_2 , ... x_n) \) 여기서 \ (x_i로부터 \ 당량 + X_ {I}. 1 \) . 작업은 키 찾을 수 있습니다 \ (키 \) 이 목록의 위치를.
예를 들어, \ (목록 = (-. 5 ,. 4 ,. 8,9 ,. 19, 81, 195, 803) \) 의 발견 \ (9 \하는) 목록의 처음 몇 개의 숫자이다.
경우 \ (키 \) 목록에서 보고서 (키 \) \ 위치, 그렇지 않으면 보고서 조회가 실패합니다. 경우 \ (키 \)의 일단에서 (반드시 인접)에 이상이 나타날 처음 나타나는 임의의 위치는 복귀된다.
이진 검색 방법은 이진 검색 방법이라고, 상기 방법은 제 1 비교 \ (키 \) 와 중간 위치들의리스트 \ (MID \) 의 핵심 요소에 대응하는 경우 \ (\ 키)(MID \) \ 동일한 요소 위치 반환 \ (MID \) . 경우 \ (키 \)는 보다 큰 \ (MID \)요소의 위치, 다음, 그렇지 않으면 나는이 목록의 왼쪽 절반에 계속 찾고, 스크립트 목록의 오른쪽 절반의 목록을보고 계속 아이까지리스트의 길이는 0입니다.
로 가정 목록 \ (L의 \)의 길이 나타낸다 \ (N을 \) 다음으로, 상기 방법이 다음과 같이 요약 될 수있다 :

  1. 初始化: \ (낮은 \의 LEFTARROW 0 \) , \ (높은 \의 LEFTARROW N \)
  2. 경우 \ (저 \ GEQ 높은 \)는 , 조회는, 알고리즘 종료 실패
  3. 计算\ (MID \ LEFTARROW \ lfloor () + 낮은 높이 / 2 \ rfloor \)
  4. 경우 \ (L [MID] == 키 \)은 리턴 \ (MID \) , 알고리즘 끝
  5. 경우 \ (L [MID]> 키 \)는 다음 \ (높은 \ 왼 화살 MID는 \) , 2 단계로 이동
  6. 경우 \ (L [MID] <키 \)은 다음 \ (MID 향하는 화살표 낮음. \ 1 + \)의 2 단계로 이동

파이썬 달성

나누기 및 정복 전략은 이진 검색 방법입니다 사용하여, 솔루션, 당신은 재귀 적 방법을 사용할 수있는 검색 공간을 줄일 수없는, 또한 순환 방식으로 구현 될 수있다.
반복적으로, 기준 상태의 반복적 시퀀스 길이가 검색 될 경우 제로이다. 비교 결과에 따라 각 재귀 시퀀스 키 중간 소자와 비교하여 차이가, 그렇지 않으면 탐색 시퀀스는 반복적으로 계속 동일하다.

def binary_search_r(lst, key, low=0, high=None):
    """
    在有序列表lst中查找key,递归实现
    @lst: 有序列表
    @key: 查找的键
    """
    if high is None:
        high = len(lst)
    if low >= high: # 基线条件
        return None
    mid = (low + high) // 2
    if key == lst[mid]: # 查找成功
        return mid
    elif key < lst[mid]:
        high = mid # 左子序列递归查找
        return binary_search_r(lst, key, low, high)
    else:
        low = mid + 1 # 右子序列查找
        return binary_search_r(lst, key, low, high)

사이클 실현은, 현재 검색의주기에 기록되어있는 경우 \ (저 \) , \ (높은 \) 이 개 위치, 중간 서열 비교 결과의 핵심 요소의 크기에 따라 검색 중 하나는 성공 또는 변경 \ (저 \) 또는 (높은 \) \ 값까지 \ (저 \ GEQ 높은 \) .

def binary_search(lst, key):
    """
    在有序列表lst中查找key,循环实现
    @lst: 有序列表
    @key: 查找的键
    """
    low = 0
    high = len(lst)
    while low < high:
        mid = (low + high) // 2
        if key == lst[mid]:
            return mid
        elif key < lst[mid]:
            high = mid
        else:
            low = mid + 1
    return None

다음은 간단한 테스트 코드는 다음과 같습니다

if __name__ == "__main__":
    x = [3, 5, 6, 7, 9, 100, 107]
    for ax in x:
        print(ax, binary_search_r(x, ax), binary_search(x, ax))
    for ax in [-5, -1, 0, 10, 105, 123]:
        print(ax, binary_search_r(x, ax), binary_search(x, ax))

이진 검색 알고리즘 분석

  • 의 정확성
    , 범위를 찾을 수 이진 검색의 각 반복이 제한됩니다 \ (낮은 \)\ (높은 \) 로 간주되는 사이에 \ (키 \) 가있는 경우 \ (L의 \) , 당신이해야합니다 이 \ (L [저] \ LEQ 키 <L [고] \) . 그래서 한이 사항이 사실과 같이 알고리즘을 수정하기 : 만약 \ (L의 \의 주요 \) , 각 반복에서, \ (L [저] \ LEQ 키 <L [고] \) 꼭 그렇지.

  • 초기화, \ (0 = 낮은, 높은 = N \) , 설립 제안.
  • 가정에서 \ (K \) 단계 문 진정한 다음이다 \ (L [low_k] \ 당량 키 <L [high_k] \) .
  • 에서 \ (K + 1 \) 단계 \ (MID = \ lfloor (low_k high_k +) / 2 \ rfloor의 \) :

    • 만약 \ (키> L [MID] \) 다음 \ (키 \) 를 만족 $의 L [미드] <키 < L [high_k] $. 새로운 서브 간격 촬영 \합니다 (I = [L [MID], L [high_k]) \) ,이 있어야 상기 I에서 \ (키 \ \) ;
    • 만약 \ (키 <L [MID] \) 다음 \ (키 \) $ L [low_k] <키 <만족 L [미드]을 $. 새로운 서브 - 서브 간격 촬영 \합니다 (I = [L [low_k], L [MID]) \) , 다음 의 I에서 \ (키 \ \) ;
    • 경우 \는 (키 = 1 [MID] \) , 다음 성공을 찾을 수 있습니다.
  • 시간 복잡도

    최악의 경우는, 키는 목록에없는 있지만, 길이 0의 마지막 순서까지 이진 검색이 중지되었습니다. 길이의 원래 시퀀스 가정 \을 (N \) , 각 반복은 절반의 범위 일 것이다. 첫번째 반복 후 불명의 시퀀스 길이 \ (N / 2 \) , 두번째 반복 후 불명의 시퀀스 길이 \ (N / 2 ^ 2 \) . 반복의 최대 수로 설정한다 (K \) \ 다음 \ (N / 2 ^ {K-. 1}>. 1, N / 2 ^ {K} \ 당량. 1 \) , 즉 \ (K = \ lceil \ log_2 N \을 rceil \) . 따라서, 길이 \ (N \) 테이블, 이진 검색의 최대 반복 횟수 \ (\ log_2 N \) , 알고리즘의 복잡성 \ (O (\ log_2N) \) .

추천

출처www.cnblogs.com/data_algorithms/p/binary_search.html