문제

봤어요 몇 가지 흥미로운 주장에서는 그래서 다시 자바 해시맵과 그들의 O(1) 조회다.고 있습니다 이렇게 하는 이유?지 않으면 이 해시맵은 다른 하나에서의 해싱 알고리즘을 나는 구입에 있어야 합 항상 존재하는 데이터 집합이 포함되어 충돌 사고로 이어질 수 있습니다.

어떤 경우에,이 조회 것 O(n)O(1).

할 수 있는 누군가가 여부를 설명들 O(1)고,그렇다면,그들은 어떻게 이것을 달성?

도움이 되었습니까?

해결책

해시 맵의 특별한 특징은 균형 잡힌 나무와 달리 행동이 확률 론적이라는 것입니다. 이 경우 일반적으로 최악의 사건이 발생할 확률 측면에서 복잡성에 대해 이야기하는 데 가장 도움이됩니다. 해시 맵의 경우, 물론지도가 얼마나 완전한 지에 대한 충돌의 경우입니다. 충돌은 추정하기 쉽습니다.

충돌 = N / 용량

따라서 적은 수의 요소조차도 해시 맵은 적어도 하나의 충돌을 경험할 가능성이 높습니다. 큰 o 표기법을 통해 우리는 더 설득력있는 일을 할 수 있습니다. 임의의 임의의 고정 상수 k에 대해 관찰하십시오.

o (n) = o (k * n)

이 기능을 사용하여 해시 맵의 성능을 향상시킬 수 있습니다. 대신 최대 2 개의 충돌 가능성에 대해 생각할 수 있습니다.

충돌 x 2 = (N / 용량)2

이것은 훨씬 낮습니다. 하나의 추가 충돌을 처리하는 비용은 큰 O 성능과 관련이 없기 때문에 실제로 알고리즘을 변경하지 않고 성능을 향상시키는 방법을 찾았습니다! 우리는 이것을 일반화 할 수 있습니다

충돌 xk = (N / 용량)케이

그리고 이제 우리는 임의의 충돌 수를 무시하고 우리가 설명하는 것보다 더 많은 충돌 가능성이 사라질 수 있습니다. 알고리즘의 실제 구현을 변경하지 않고 올바른 k를 선택하여 임의로 작은 레벨로 확률을 얻을 수 있습니다.

해시 맵에는 O (1) 액세스가 있다고 말함으로써 이것에 대해 이야기합니다. 확률이 높습니다

다른 팁

당신은 최악의 행동을 평균 사례 (예상) 런타임과 혼합하는 것 같습니다. 전자는 실제로 해시 테이블에 대한 O (N)이지만 (즉, 완벽한 해싱을 사용하지 않음) 실제로는 거의 관련이 없습니다.

반 괜찮은 해시와 결합 된 신뢰할 수있는 해시 테이블 구현은 매우 좁은 분산 마진 내에 예상되는 경우에 매우 작은 요인 (2, 실제로)과 함께 O (1)의 검색 성능을 가지고 있습니다.

Java에서 Hashmap은 해시 코드를 사용하여 버킷을 찾아 작동합니다. 각 버킷은 해당 버킷에 상주하는 항목 목록입니다. 비교를 위해 동등한 항목을 스캔합니다. 항목을 추가 할 때 해시 맵은 특정 하중 백분율에 도달하면 크기가 조정됩니다.

따라서 때로는 몇 가지 항목과 비교해야하지만 일반적으로 O (N)보다 O (1)에 훨씬 가깝습니다. 실제적인 목적을 위해, 그것이 당신이 알아야 할 전부입니다.

o (1)은 각 조회가 단일 항목 만 검사한다는 것을 의미하지는 않습니다. 확인 된 평균 품목 수는 컨테이너의 항목 수를 일정하게 유지한다는 것을 의미합니다. 따라서 100 개 항목이있는 컨테이너에서 항목을 찾는 데 평균 4 번의 비교가 필요한 경우, 10000 개의 항목이있는 컨테이너에서 항목을 찾는 데 평균 4 개의 비교가 필요하고 다른 수의 항목에 대해서는 평균 4 가지 비교가 필요합니다 (항상 약간의 분산, 특히 해시 테이블이 다시 시작되는 지점과 매우 적은 수의 항목이있을 때).

따라서 충돌로 인해 버킷 당 평균 키 수가 고정 된 경계 내에 남아있는 한 컨테이너가 O (1) 작동을 방해하지 않습니다.

나는 이것이 오래된 질문이라는 것을 알고 있지만 실제로는 새로운 답이 있습니다.

해시지도가 실제로는 아니라고 말합니다 O(1), 엄격하게 말하면, 요소의 수가 임의로 크게 증가함에 따라 결국 일정한 시간에 검색 할 수 없기 때문에 (그리고 O- notation은 임의로 커질 수있는 숫자로 정의됩니다).

그러나 실시간 복잡성은 O(n)-버킷을 선형 목록으로 구현해야한다는 규칙이 없기 때문에.

실제로 Java 8은 버킷을 구현합니다 TreeMaps 임계 값을 초과하면 실제 시간을 만듭니다. O(log n).

버킷 수 (B 호출)가 일정하게 유지되면 (일반적인 경우) 조회는 실제로 O (n)입니다.
N이 커짐에 따라 각 버킷의 요소 수는 평균 N/B입니다. 충돌 해상도가 일반적인 방법 중 하나 (예 : 링크 된 목록)로 수행되면 조회는 O (N/B) = O (N)입니다.

O 표기법은 N이 점점 커지면 어떻게되는지에 관한 것입니다. 특정 알고리즘에 적용될 때 오해의 소지가있을 수 있으며 해시 테이블이 그 예입니다. 우리는 우리가 처리 할 요소 수에 따라 버킷 수를 선택합니다. n이 b와 거의 같은 크기 인 경우, 조회는 대략 일정한 시간이지만 O는 O (1)라고 부를 수 없습니다.

O(1+n/k) 어디 k 버킷 수입니다.

구현이 설정된 경우 k = n/alpha 그렇다면 그것은입니다 O(1+alpha) = O(1) ~부터 alpha 상수입니다.

우리는 해시 테이블 조회에 대한 표준 설명이 O (1) 인 엄격한 최악의 성능이 아니라 평균 사례 예상 시간을 나타냅니다. 체인 (Java 's Hashmap)과의 충돌을 해결하는 해시 테이블의 경우 기술적으로 O (1+α)입니다. 좋은 해시 기능, 여기서 α는 테이블의 하중 계수입니다. 저장하는 객체의 수가 테이블 크기보다 일정한 요인에 지나지 않는 한 여전히 일정합니다.

또한 엄격하게 말하면 O (O)를 구축 할 수 있다고 설명했다.N) 결정 론적 해시 기능에 대한 조회. 그러나 최악의 사례를 고려하는 것도 흥미 롭습니다 예상되는 평균 검색 시간과는 시간입니다. 체인 사용 이것은 O (1 + 가장 긴 체인의 길이)입니다. 예를 들어 θ (로그 N / 로그 로그 N) α = 1 일 때.

일정한 시간을 달성하는 이론적 인 방법에 관심이 있다면 최악의 최악의 조회를 읽을 수 있습니다. 역동적 인 완벽한 해싱 다른 해시 테이블과 재귀 적으로 충돌을 해결합니다!

해싱 기능이 매우 양호한 경우에만 O (1)입니다. Java Hash 테이블 구현은 잘못된 해시 기능으로부터 보호하지 않습니다.

항목을 추가 할 때 테이블을 키워야하는지 여부는 조회 시간에 관한 것이기 때문에 질문과 관련이 없습니다.

요소의 내부에 HashMap 로 저장되는 배열의 링크 목록(노드),각각 연결 목록에 배열을 나타내는 버킷에 대한 독특한 해쉬값을 하나 이상의 키를 사용합니다.
를 추가하는 동안 항목에서 HashMap,이 해시 코드의 키를 사용하는 위치를 확인하려면의 물통에서 배열,다음과 같습니다.

location = (arraylength - 1) & keyhashcode

여기&을 나타내는 비트와 연산자입니다.

예를 들어: 100 & "ABC".hashCode() = 64 (location of the bucket for the key "ABC")

하는 동안 얻을 작업에 사용하는 동일한 방법의 위치를 결정하는 버킷 위한 핵심입니다.아래에서 최상의 경우에 각 키에는 유일한 차이와 결과에서 고유한 물통에 대한 각각의 키,이 경우에 얻는 방법을 보낸 시간을 확인하기 위해서만 양동이 위치하고 값을 검색하는 일정한 O(1).

최악의 경우에 따라,모든 키는 같은 해시에 저장하고 동일한 버킷,이 결과를 가로지르는 전체 목록을 지도하는 O(n).

의 경우에는 java8,연결 목록 물통은 대체로 다루는 경우는 크기 성장을 8 개 이상이 감소는 최악의 경우 검색의 효율성을 O(로그 n).

이는 기본적으로 알고리즘 자체가 실제로 변하지 않기 때문에 대부분의 프로그래밍 언어에서 대부분의 해시 테이블 구현에 적용됩니다.

테이블에 충돌이없는 경우 단일 조회 만 수행하면 실행 시간이 O (1)입니다. 충돌이있는 경우 하나 이상의 조회를 수행하여 O (N)을 향한 성능을 낮추어야합니다.

충돌을 피하기 위해 선택한 알고리즘에 따라 다릅니다. 구현에서 별도의 체인을 사용하는 경우 모든 데이터 요소가 동일한 값으로 해시되는 경우 최악의 시나리오가 발생합니다 (예 : 해시 기능의 불량 선택). 이 경우 데이터 조회는 링크 된 목록의 선형 검색과 다르지 않습니다. 그러나, 그러한 일이 일어날 확률은 무시할 수 없으며 조회는 최고이며 평균 사례는 일정하게 유지됩니다 (1).

학계를 제외하고 실질적인 관점에서 해시 맵은 중요하지 않은 성능 영향을받는 것으로 받아 들여 져야합니다 (프로파일 러가 다른 말을하지 않는 한).

이론적 인 경우에만 해시 코드가 항상 다르고 모든 해시 코드의 버킷도 다르면 O (1)이 존재합니다. 그렇지 않으면, 그것은 일정한 순서, 즉 해시 맵의 증가에 따라, 검색 순서는 일정하게 유지된다.

물론 해시 맵의 성능은 주어진 객체에 대한 hashcode () 함수의 품질에 따라 달라집니다. 그러나 충돌 가능성이 매우 낮도록 함수가 구현되면 성능이 매우 우수합니다 (이것은 엄격하게 O (1)가 아닙니다. 모든 가능한 경우 대부분 케이스).

예를 들어 Oracle JRE의 기본 구현은 랜덤 숫자를 사용하는 것입니다 (객체 인스턴스에 저장되어 변경되지 않도록하지만 바이어스 잠금을 비활성화하지만 다른 논의입니다). 충돌 가능성은 충돌 가능성이 있습니다. 매우 낮은.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top