이진 검색이 삼진 검색보다 빠른 이유는 무엇입니까?


49

이진 검색을 사용하여 요소 의 배열을 검색하려면 최악의 경우 반복이 필요합니다. 각 단계에서 검색 공간의 절반을 잘라 내기 때문입니다. 대신 '삼항 검색'을 사용하는 경우 각 반복마다 검색 공간의 3 분의 2를 잘라내므로 최악의 경우 반복 ...Nlog2Nlog3N<log2N

삼항 검색이 더 빠른 것 같습니다. 왜 이진 검색을 사용합니까?


3
4 차 검색에 대해 동일한 추론을 사용할 수 없습니까? 또는 십진 검색 ... 또는 2보다 큰 것
d' alar'cop

4
B + Trees
arunmoezhi

5
캐시 검색 일관성이 있고 거의 모든 브랜치가 올바르게 예측되기 때문에 선형 검색은 최신 하드웨어의 중소형 문제에 대한 이진 검색보다 빠릅니다.
가명

2
또한 직감력을 나타내는 2 * log_3 (N) = log_3 (N ^ 2)입니다.
PawelP

6
이것을 직관적 인 용어로 보자. 반복 할 때마다 검색 공간이 더 많이 줄어들 기 때문에 3 기반 검색을 사용하는 것이 더 빠르다면 백만 기반 검색을 더 빨리 사용하지 않습니까? 그러나 대상을 포함하는 1 백만 개의 슬라이스를 결정하려면 각 반복 내에서 평균적으로 500,000 개의 검사를 수행해야한다는 것을 쉽게 알 수 있습니다. 분명히 검색 공간을 각 반복의 절반 이상으로 줄이면 더 많은 정보를 한 번에 확실하게 얻을 수 있습니다.
ErikE

답변:


76

이진 검색을 적용하면 많은 비교가 있습니다. 삼항 검색을 적용하는 경우 각 단계에서와 같이 많은 비교가 이루어집니다. 각 단계에서 검색 공간을 세 부분으로 자르려면 2 개의 비교를 수행해야합니다. 이제 수학을 수행하면 다음을 관찰 할 수 있습니다. 우리가 알고 있기 때문에 그 , 우리가 실제로 얻을 삼항 검색과 비교를.

log2(n)+O(1)
2log3(n)+O(1)
2log3(n)+O(1)=2log(2)log(3)log2(n)+O(1)
2log(2)log(3)>1

그건 그렇고 : 비교가 상당히 비싸고 병렬화 될 수있는 경우 병렬 컴퓨터가 적용될 수있는 경우 -ary 검색은 의미가 있습니다.n

인수는 -ary 검색으로 매우 쉽게 일반화 될 수 있습니다. 함수 이 정수 값에 대해 엄격하게 모노톤 증가 함 을 보여 주면 됩니다.f ( k ) = ( k 1 ) 로그 ( 2 )n kf(k)=(k1)log(2)log(k)k


1
그리고 좌 감사합니다 ....이 4 차 또는 그 이상의 뭔가 .... 멋진 설명을 위해 도움이되지 않도록 선형 및 RHS가 로그입니다
평균 제곱

3
완전성을 위해서만 : 요소 비교 횟수와 같은 추상 측정 값이 실제 런타임을 지배하거나 지배하지 않을 수 있습니다. 특히, 어느 검색으로도 긴 어레이에서 발생할 수있는 캐시 미스 수를 고려해야합니다. (여기서 그들은 일치한다. 나는 OP가 "왜 더 빠를까?"라고 묻기 때문에이 점에 주목하고있다. 추상적 인 척도로 대답하면 일부 알고리즘에서는 오도 할 수있다.)
Raphael

10
삼항 검색에서는 1/3의 시간 만 1 개의 비교 만 필요합니다 (낮은 비교 : 낮은 3 분의 1이면 두 번째 비교가 필요하지 않음). 이는 25 % 대신 3 % 만 느리게 만듭니다 (이 세상에서는 비교 횟수에만 관심이 있습니다). 바이너리보다 빠르지는 않지만 의심 할 여지가 있지만 n-ary로 일반화하는 방법을 모르겠습니다.
Aaron Dufour

2
@AaronDufour : 중간 항목을 먼저 비교 한 다음 다른 비교 결과를 무시하여 4 차 검색을 수행 할 수 있으므로 3 차 비교가 두 번의 비교보다 병렬로 더 저렴하게 병렬로 수행 될 수있는 경우 4 차 검색이 더 빠를 수있는 유일한 방법은 순차적으로 수행 할 수 있습니다.
supercat

1
@AaronDufour 그러나 검색 할 요소를 상각하고 있으며 왜 그런지 잘 모르겠습니다. 최악의 경우 두 단계 모두 비교할 수 있습니다.
Sasho Nikolov

26

DCTLib은 옳지 만 잠시 수학을 잊어라.

당신의 논리에 따르면, n -ary가 가장 빠릅니다. 그러나 당신이 그것에 대해 생각하면, n -ary는 정규 반복 검색과 정확히 동일합니다 (목록을 1에서 1까지 반복하지만 역순으로). 먼저 목록에서 마지막 (또는 마지막) 항목을 선택하고 해당 값을 비교 값과 비교하십시오. 그런 다음 목록에서 해당 항목을 제거한 다음 새 목록에서 마지막 항목 (배열의 마지막 값 옆에있는)을 선택하십시오. 매번 값을 찾을 때까지 한 번에 하나의 값만 제거합니다.

대신, 당신은 이것에 대해 생각해야합니다-각 반복에서 목록에서 가장 많은 값을 어떻게 제거합니까? 이진 검색에서는 항상 목록의 절반을 제거합니다. 삼항 검색에서는 목록의 2/3를 제거 할 가능성이 있지만 (실제로는 33.33 %) 목록의 1/3 만 제거 할 가능성이 훨씬 더 높습니다 (66.66 %). O (n)을 계산하려면 최악의 시나리오 (1/3, 1/2 미만)를 살펴 봐야합니다. n에 가까워 질수록 더 나빠집니다.

이진 검색을 통해 최악의 시나리오가 개선 될뿐만 아니라 평균 시간도 향상됩니다. 예상 값 (평균적으로 목록에서 제거 할 수있는 부분)을 살펴보면 다음 공식을 사용합니다.

(P_lower) x (낮은 경우 제거 할 수있는 부분) + (P_higher) x (높은 경우 제거 할 수있는 부분) = E

이진 검색의 경우 이것은 .5x.5 + .5x.5 = .5입니다 (우리는 항상 목록의 절반을 제거합니다). 삼항 검색의 경우이 값은 .666x.333 + .333x.666 = 0.44이거나 각 단계에서 목록의 44 % 만 제거하므로 평균적으로 이진 검색보다 효율성이 떨어집니다. 이 값은 1/2 (목록의 절반)에서 정점에 도달하고 n (역 반복) 및 0 (정기 반복)에 가까워 질수록 감소합니다.

좋아, 그래서 나는 거짓말했다. 약간의 수학이 관련되어 있지만, 그것이 도움이되기를 바랍니다!


1
이것은 좋은 대답입니다.
The_Sympathizer

Ya 경계 분석은 어려운 수학을 이해하는 데 도움이됩니다! n- 순차 검색은 동일한 선형 검색 비용 O (n)입니다.
shuva

-2

log (N) vs 2 log (N) 비교 인수는 알고리즘의 순진한 해석을 기반으로합니다. 실제로 앉아서 x86 어셈블리에 이것을 쓰면 결과가 반전됩니다. 문제는 테스트 케이스에 정수를 사용하여 중복 비교를 제거 할 수없는 불충분하게 똑똑한 컴파일러와 결합하는 것입니다. 문자열과 적절한 문자열 비교 함수로 다시 시도하고 루프 당 한 번 비교 함수를 호출하도록 코딩하면 삼항 검색이 다시 빠릅니다.


2
물론 반복 당 하나의 비교만으로 삼항 검색을 수행하면 더 빠릅니다. 그러나 문자열이나 정수에 관계없이 할 수 없습니다.
FrankW

비교는 중복되지 않으며 문제는 컴파일러와 관련이 없습니다. 검색 공간을 세 부분으로 나누려면 두 가지 비교가 필요합니다. 이진 검색에서는 중간 요소와 비교하기 만하면 검색 공간의 절반이 결과에 포함될 수 있음을 알 수 있습니다. 삼진 검색의 경우 요소의 1/3과 비교해야합니다. 그리고 목록 전체의 2/3를 나열하십시오. 비교하는 데이터 유형 또는 사용중인 언어는 관련이 없습니다. 품목이 1 일 3 일 경우 1 번 비교 후 중지 할 수 있습니다.
reirab

2
일부 플랫폼에서는 비교를 위해 CPU가 피연산자를 RAM에서 가져 오는 데 더 많은 시간을 허용하기 때문에 3 진 검색이 더 빠를 수 있습니다. 그러나 이는 사용되는 플랫폼과 지연 시간 및 캐시에 전적으로 달려 있습니다.
jpa

1
이건 삼항 검색의 잘못된 정의입니다.
Joshua
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.