Joe의 답변은 매우 훌륭하며 모든 중요한 키워드를 제공합니다.
간결한 데이터 구조 연구는 아직 초기 단계에 있으며 많은 결과는 대체로 이론적입니다. 제안 된 데이터 구조는 구현하기가 상당히 복잡하지만 대부분의 복잡성은 유니버스 크기와 저장된 요소 수 모두에서 점근 적 복잡성을 유지해야하기 때문입니다. 이들 중 하나가 비교적 일정하면 많은 복잡성이 사라집니다.
컬렉션이 반 정적 인 경우 (즉, 삽입물이 드물거나 최소한 소량) 업데이트와 함께 구현하기 쉬운 정적 데이터 구조 (Sadakane의 sdarray가 좋습니다)를 고려할 가치가 있습니다. 은닉처. 기본적으로 기존 데이터 구조 (예 : B- 트리, 트리, 해시 테이블)에 업데이트를 기록하고 "메인"데이터 구조를 주기적으로 대량 업데이트합니다. 반전 된 인덱스는 검색에 많은 이점이 있지만 그 자리에서 업데이트하기 어렵 기 때문에 정보 검색에서 매우 널리 사용되는 기술입니다. 이 경우 의견에 알려주십시오.이 답변을 수정하여 몇 가지 조언을 드리겠습니다.
삽입이 더 빈번하다면 간결한 해싱을 제안합니다. 기본 아이디어는 여기에 설명하기에 간단합니다. 그렇게하겠습니다.
따라서 기본 정보 이론적 결과는 항목 의 유니버스에서 요소를 저장 하고 다른 정보가없는 경우 (예 : 요소 간의 상관 관계가없는 경우) 그것을 저장하는 비트. (달리 명시되지 않는 한 모든 로그는 밑이 2입니다.) 이 비트 가 필요 합니다. 그 주위에 방법이 없습니다.nu로그(유엔) +O(1)
이제 몇 가지 용어 :
- 데이터를 저장하고 비트의 공간 에서 작업을 지원할 수있는 데이터 구조가있는 경우 이를 암시 적 데이터 구조라고합니다.로그(유엔) +O(1)
- 데이터를 저장하고 데이터를 저장할 수있는 데이터 구조가있는 경우 비트의 공간을 하면이 데이터를 컴팩트 한 데이터 구조라고합니다. 실제로 이것은 이론상 최소값에 상대적인 상대적 오버 헤드가 일정하다는 것을 의미합니다. 5 % 오버 헤드, 10 % 오버 헤드 또는 10 배 오버 헤드 일 수 있습니다.로그(유엔) +O(로그(유엔) )=(1+O(1))로그(유엔)
- 데이터를 저장하고 작업을 지원할 수있는 데이터 구조가있는 경우 공간의 비트를 하면 간결한 데이터 구조라고합니다.로그(유엔) + o ( 로그(유엔) )=(1+o( 1 ) ) 로그(유엔)
간결함과 컴팩트 함의 차이는 little-oh와 big-oh의 차이입니다. 잠시 동안 절대 값을 무시하는 중 ...
- 지( n ) = O ( f( n ) ) 은 모든 , 과 같이 상수 와 숫자 이 있음을 의미합니다 .씨엔0n >엔0지( n ) < c ⋅ f( n )
- 지( n ) = o ( f( n ) ) 은 모든 상수 에 대해 , 과 같은 숫자가 있음을 의미합니다 .씨엔0엔>엔0지( n ) < c ⋅f( n )
비공식적으로, big-oh 및 little-oh는 모두 "상수 요소 내"이지만, big-oh를 사용하면 알고리즘 알고리즘, CPU 제조업체, 물리 법칙 등에 의해 상수가 선택되지만 -오직 상수를 직접 선택하면 원하는만큼 작을 수 있습니다 . 간결한 데이터 구조를 사용하면 문제의 크기가 커질수록 상대적인 오버 헤드가 임의로 작아집니다.
물론, 원하는 상대적인 오버 헤드를 실현하기 위해 문제의 크기가 커져야 할 수도 있지만 모든 것을 가질 수는 없습니다.
자, 우리 벨트 아래에 문제에 대한 숫자를 적어 봅시다. 키가 비트 정수 (유니버스 크기는 )라고 가정하고 의 정수 를 저장하려고합니다 . 완벽한 점유율과 낭비없이 이상적인 해시 테이블을 마술처럼 정렬하여 정확히 해시 슬롯이 필요하다고 가정 해 봅시다 .엔2엔2미디엄2미디엄
조회 작업은 비트 키를 해시하고 비트를 마스크 해제 하여 해시 슬롯을 찾은 다음 테이블의 값이 키와 일치하는지 확인합니다. 여태까지는 그런대로 잘됐다.엔미디엄
이러한 해시 테이블은 비트를 사용합니다. 이보다 더 잘할 수 있습니까?엔2미디엄
해시 함수 가 뒤집을 수 없다고 가정하십시오 . 그런 다음 각 해시 슬롯에 전체 키를 저장할 필요가 없습니다. 해시 슬롯의 위치는 비트의 해시 값을 제공하므로 남은 비트 만 저장 한 경우이 두 가지 정보 (해시 슬롯 위치 및 저장된 값)에서 키를 재구성 할 수 있습니다. 따라서 비트의 저장 공간 만 있으면 됩니다.h미디엄n - m( n - m )2미디엄
경우 비교 작 , 스털링 근사 조금 산술 (! 증거 운동 임) 것을 알 :2미디엄2엔
( n - m )2미디엄= 로그(2엔2미디엄) +o(로그(2엔2미디엄) )
따라서이 데이터 구조는 간결합니다.
그러나 두 가지가 있습니다.
첫 번째 캐치는 "좋은"가역적 인 해시 함수를 만드는 것입니다. 다행히도 이것은보기보다 훨씬 쉽습니다. 암호 전문가는 항상 뒤집을 수없는 기능을 만들고 오직 "암호 자"라고 부릅니다. 예를 들어, Feistel 네트워크를 기반으로 해시 함수를 만들 수 있는데, 이는 비가역 해시 함수에서 비가역 해시 함수를 구성하는 간단한 방법입니다.
두 번째는 생일 역설 덕분에 실제 해시 테이블이 이상적이지 않다는 것입니다. 따라서 더 복잡한 유형의 해시 테이블을 사용하여 유출없이 전체 점유율에 더 가까이 다가 가고 싶습니다. 뻐꾸기 해싱은 이론에 이상적으로 접근 할 수 있고 실제로는 매우 근접 할 수 있기 때문에 완벽합니다.
뻐꾸기 해싱에는 여러 해시 함수가 필요하며 해시 슬롯의 값에 사용 된 해시 함수 태그가 필요합니다. 예를 들어 네 개의 해시 함수를 사용하는 경우 각 해시 슬롯에 추가 2 비트를 저장해야합니다. 이것은 이 자라 면서 간결 하므로 실제로 문제가되지는 않지만 전체 키를 저장하는 것보다 여전히 뛰어납니다.미디엄
아, 당신은 또한 반 엠드 보아스 나무를보고 싶을 수도 있습니다.
더 생각
경우 어딘가에있다 , 다음 약 값과 더 상관 관계가 없다고 가정 때문에 (다시 한번), 당신은 기본적으로 작업을 수행 할 수 비트 벡터보다 낫습니다. 위의 해싱 솔루션은이 경우 효과적으로 해체되지만 (해시 슬롯 당 1 비트를 저장하게 됨) 해시 함수를 사용하는 대신 키를 주소로 사용하는 것이 더 저렴합니다.엔유2로그(유엔)유
이 매우 가까운 경우 모든 간결한 데이터 구조 문헌에서 사전의 의미를 뒤집을 것을 권장합니다. 세트에서 발생 하지 않는 값을 저장하십시오 . 그러나 이제 삭제 작업을 효과적으로 지원하고 간결한 동작을 유지하려면 더 많은 요소가 "추가"될 때 데이터 구조를 축소 할 수 있어야합니다. 해시 테이블 확장은 잘 이해 된 작업이지만 계약하지는 않습니다.엔유