별도의 체인에 이진 검색 트리를 사용하여 해시 테이블의 속도를 높일 수 있습니까?


11

이진 검색 트리를 사용하여 해시 테이블을 구현하여 O (n) (연결된 목록 사용)에서 O (log n) (BST 사용)로 분리 체인 프로세스의 검색 복잡성을 줄이려고합니다. 이것이 가능합니까? 그렇다면 그렇다면 어떻게해야합니까? 솔루션이 단계별로 로직을 구현하는지 이해하는 것이 더 쉬울 것입니다.

해시 테이블 (검색 별도의 체인을 사용하여 빌드)에서 검색 시간을 줄이고 싶지만 동시에 삽입 시간을 늘리고 싶지 않습니다. 내 프로젝트의 경우 충돌을 줄이기 위해 해시 기능을 변경할 수 없습니다. 그러나 확장 성으로 인해 충돌이 발생합니다. 해결 방법을 찾으려고합니다. 그래서 충돌이 발생하는 경우 (예 : 전체 알고리즘을 재구성하는 것보다 현재 상태를 관리하는 경우) 최상의 액세스 및 삽입 시간으로 작업 할 수 있습니다. 팬 아웃되지 않으면 재구성해야합니다. 어떤 아이디어?


4
해시 테이블과 이진 검색 트리는 다른 컨테이너입니다. 그래서 당신은 당신이 제안하는 것을 할 수 없습니다 (또는 당신은 용어적인 실수를하고 있습니다).
Basile Starynkevitch

나무의 각 노드에 해시 / 값 쌍을 넣을 수는 있지만 해시 테이블이나 이진 트리가 잘못되었을 수 있습니다. 왜 당신이 이것을하고 싶고 최종 결과가 가능하기를 원하는지에 대한 설명이 없으면 이것이 실제로 대답 할 수 있는지 확신 할 수 없습니다.
Ixrec

1
@AK_ : 네가 말했듯이 그래. 이진 검색 트리를 사용하여 충돌을 처리하고 싶습니다. 더 명확하게하기 위해 내 질문을 약간 수정했습니다.
Aviral

1
그러면 모든 인서트에 대해 O (n log n) 의 패널티 가 제공됩니다 . 일반적으로 해시 테이블이 너무 가득 차기 시작하면 (그리고 허용 할 수있는 것보다 긴 체인이있는 경우) 해시를 다시 작성합니다. 정기적으로 3 또는 4보다 긴 체인을 발견하면 문제가있는 것입니다.

3
해시 테이블에는 테이블의 충돌 감소, 열린 주소 지정 및 동적 크기 조정을 위한 수많은 변형 이 있습니다 . 어느 것이 요구 사항에 맞는지 살펴 봐야합니다. 현재 접근 방식은 다른 구조와의 별도 체인

답변:


11

당신이 요구하는 것은 당신의 제약이 주어지면 가능합니다.

분석

해시 테이블의 장점은 빠른 조회 및 삽입 속도입니다. 그 속도를 얻으려면 테이블에서 순서의 유사성을 잊어 버려야합니다. 즉, 항목이 모두 뒤죽박죽입니다. 순회가 O (n) 인 동안 해시 테이블이 충분히 크고 테이블에 저장된 오브젝트가 우수한 품질의 해싱 알고리즘을 사용하여 해시되는 것으로 가정하므로 목록은 테이블 항목으로 사용할 수 있습니다.

이진 검색 트리 (BST)는 O (log 2 n) 에서 빠른 삽입 및 조회 기능을 제공 합니다. 또한 저장하는 요소에 제한을가합니다. 요소를 주문하는 방법이 있어야합니다. 트리에 저장된 두 개의 요소 AB가 주어지면 AB 보다 앞에 오는지 또는 동등한 순서 를 갖는지 확인할 수 있어야합니다 .

해시 테이블에는 이러한 제한이 없습니다. 해시 테이블의 요소에는 두 가지 속성이 있어야합니다. 첫째, 그것들이 동등한지를 결정하는 방법이 있어야합니다. 둘째, 결정적 해시 코드를 계산하는 방법이 있어야합니다. 주문은 필수 요건이 아닙니다.

해시 테이블 요소에 순서가있는 경우 BST를 해시 테이블 항목으로 사용하여 동일한 해시 코드 (충돌)를 가진 오브젝트를 보유 할 수 있습니다. 그러나 O (log 2 n) 조회 및 삽입 이있는 BST로 인해 전체 구조 (해시 테이블 + BST)에 대한 최악의 경우가 목록을 테이블 항목으로 사용하는 것보다 기술적으로 우수합니다. BST 구현에 따라 목록보다 많은 스토리지가 필요하지만 그다지 많지는 않습니다.

일반적으로 BST의 오버 헤드와 동작은 실제 상황 에서 해시 테이블 버킷으로 테이블 아무 것도 가져 오지 않으므로 목록의 이론적 인 성능 저하가 허용됩니다. 즉, 해시 테이블은 각 목록 (버킷)에 더 적은 수의 항목을 배치하여 목록의 약점을 보상합니다. 그러나 문제는 해시 테이블의 크기를 늘릴 수 없으며 해시 테이블 에서 일반적인 것보다 충돌이 더 자주 발생한다는 점입니다.

이행

솔직히 필요하지 않으며 어쨌든 언어를주지 않았기 때문에 여기에 코드를 넣지 않을 것입니다.

내가 할 일은 단순히 언어의 표준 라이브러리에 포함 된 표준 해시 테이블을 새 클래스로 복사 한 다음 테이블 버킷 유형을 목록에서 트리로 변경하는 것입니다. 언어와 표준 라이브러리에 따라이 작업은 매우 간단 할 수 있습니다.

일반적으로 나는 이와 같은 복사 및 붙여 넣기 코딩을 옹호하지 않을 것입니다. 그러나 전투 테스트를 거친 데이터 구조를 매우 빠르게 얻는 쉬운 방법 입니다.


점근 적 측면에서, 충돌 처리를 위해 이진 트리를 사용하여 해시 테이블의 예상 성능은 변경되지 않습니다 제공 해시 테이블이 이미 어쨌든 상각 O (1)의 성능을 달성하기 위해 일반적인 트릭을했다는 것을합니다. 좋은 성능을 보장하기 위해 해시 테이블의 크기를 조정하면 버킷 당 예상 항목 (이진 트리의 크기)도 작을 것으로 예상되므로 동일한 예상 상각 O (1)로 끝납니다. 최악의 경우에도-밸런싱 제약 조건이 지정되지 않은 경우 이진 트리의 최악의 성능은 결국 링크 된 목록처럼 작동한다는 것입니다.
Steve314

@ Steve314 문제는 충돌이 많이 발생하므로 버킷에 일반적으로 해시 테이블보다 많은 항목이 포함될 것으로 예상합니다.

좋은 점-예를 들어 무제한 데이터를 가진 일정한 크기의 해시 테이블의 경우 해시 테이블의 점근 성능은 충돌 처리의 점근 성능과 동일합니다. 해시 테이블은 상수 요인 만 변경합니다.
Steve314

기본적으로 해시 테이블이 각 버킷의 요소 수를 효과적으로 제한 할 수없는 경우 각 버킷에서 사용되는 하위 데이터 구조로 점근 적 성능이 저하됩니다. 나는 이것을 명확하게하기 위해 내 대답에 단락을 추가했습니다.

7

해시 테이블에서 충돌 처리에 이진 트리를 사용하는 것은 불가능할뿐만 아니라 이미 완료되었습니다.

Walter BrightD 프로그래밍 언어 의 발명가로 잘 알려져 있지만 DMDScript 라는 ECMAScript 변형을 작성했습니다 . 과거에는 DMDScript (또는 조상-아마도 DScript라는 이름을 기억하는 것)의 헤드 라인 주장은 해시 테이블이 많은 유사한 언어로 된 것보다 성능이 뛰어나다는 것입니다. 이유는 이진 트리를 사용한 충돌 처리입니다.

나는 이것이 어디에서 왔는지 정확히 기억하지 못하지만 사용 된 나무는 순진 이진 트리였으며 부분 균형 구성표 (AVL, 빨강-검정 또는 기타가 아님)가 없으며 해시 테이블 자체가 가득 차면 크기가 조정된다고 가정하는 것이 합리적입니다. 터무니없이 임박한 해시 충돌 속도를 얻지 못하면 이진 트리는 항상 작아야합니다. 기본적으로 최악의 경우는 충돌 처리에 링크 된 목록을 사용하는 것과 동일하지만 (한 노드 대신 두 개의 포인터 가격을 지불하는 것을 제외하고) 평균 경우는 각 해시 버킷 내에서 검색 량을 줄입니다.

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