Insert, Delete 및 MostFrequent를 지원하는 효율적인 데이터 구조


14

우리가 설정되어 있다고 가정 및 각 부재 데이터 및 키 쌍이다. 다음 작업을 지원하는 데이터 구조가 필요합니다.DDD

  • 를 삽입 하고D(d,k)D
  • 삭제 멤버 , (필요 찾기 위해 검색하지 않으려면 , 예를 들면 의 구성원 포인트 )e e DeeeD
  • 멤버 반환 MostFrequent, 하도록 가장 빈번한 키 중 하나 인 (가장 빈번한 키를 고유 할 필요가 없다는 것을 참고).e . k는 전자 Y D를eDe.keyD

이 데이터 구조의 효율적인 구현은 무엇입니까?

내 솔루션은 빈도와 빈도에 의해 우선 순위가 지정된 키 및 해당 빈도에 대한 힙입니다. 해시 함수는 동일한 키를 가진 멤버를 해시 테이블의 동일한 슬롯에 매핑합니다 (각 부분의 포인터).

이것은 줄 수 의 처음 두 작업과 Θ ( 1 ) 세 번째 (최악의 경우의 실행 시간).Θ(lgn)Θ(1)

더 효율적인 솔루션이 있는지 궁금합니다. (또는 같은 효율성을 가진 더 간단한 솔루션?)


원하는 경우 해시 테이블 대신 간단한 균형 이진 검색 트리를 사용할 수 있습니다.
Joe

해시 테이블은 불필요한 공간을 많이 사용하므로 우선 순위 대기열을 제안합니다. 삽입 및 삭제시 동일한 시간 복잡성을 제공하지만 메모리 복잡성이 더 좋습니다.
Bartosz Przybylski 21

@Joe, 해시 테이블 대신 BST를 사용하면 MostFrequent 작업의 효율성이 떨어지지 만 메모리에 대한 합리적인 절충이 될 수 있습니다.
Kaveh

2
비교 만 사용하는 경우 요소 구별 문제의 하한으로 인해 Insert / MostFrequent 중 하나 이상이 으로 상각되어야 합니다. Ω(로그)
Aryabhata

1
스트리밍 모델에는 흥미로운 구조도 있습니다. springerlink.com/content/t17nhd9hwwry909p
Joe

답변:


7

비교 기반 계산 모델에서 일반 힙 대신 피보나치 힙을 사용하여 우선 순위 큐를 구현할 수 있습니다. 이렇게하면 다음과 같은 한계가 있습니다. 삽입에 대한 상각 시간 및 삭제 조작에 대한 상각 시간 O ( log n ) .O(1)O(logn)

비교 기반 모델에서 출발하고 키가 하나 이상의 기계어에 포함 된 이진 문자열로 간주되는 RAM 모델을 채택하는 경우 우선 순위 대기열을 구현할 수 있습니다 . 실제로 삽입 및 삭제 작업을 모두 수행 할 수 있습니다. O ( o(logn)findMin 작업의 log log n )O(1)시간입니다. Thorup은O(loglogn)O(1)

키당 시간 S ( n ) 에서 키를 정렬 할 수있는 경우 상수 시간으로 find-min을 지원하고 S ( n ) 시간으로 업데이트 (삽입 및 삭제)를 지원하는 우선 순위 대기열을 구현할 수 있습니다 .nS(n)S(n)

M. Thorup을 참조하십시오. 우선 순위 대기열과 정렬 사이의 동등성, 2002. Proc. FOCS 2002

O로 정렬 할 수 있기 때문에 ( n 예상 시간 및 선형 공간O(nloglogn)

Y. Han and M. Thorup. O의 정수 정렬 ( n 예상 시간 및 선형 공간. Proc. FOCS 2002O(nloglogn)

한계가 입증되었습니다.


1

예상 상각 시간 에이 모든 작업을 수행 할 수 있습니다 . 중요한 트릭은 각 삽입 또는 삭제 중에 키 빈도가 1 씩만 변경되므로 우선 순위 큐의 모든 기능이 필요하지 않다는 것입니다.O(1)

아래의 내 솔루션은 실제로이 경우에 효과가있는 "비효율적"우선 순위 대기열이있는 솔루션입니다. 이중으로 연결된 키 버킷 목록으로 구현 된 최대 우선 순위 대기열에는 O (1) insertMin, deleteMax, removeFromBucket 및 증가 키.


이중으로 연결된 버킷 목록을 유지합니다. 각 버킷에는 비어 있지 않은 해시 키 집합 (코호트라고 함)과 양의 정수 (ValCount라고 함)가 있습니다. 버킷 b에서 b의 코호트에있는 각 키 k는 유지 관리중인 세트에서 동일한 수의 고유 값을 갖습니다. 예를 들어, 세트에 (a, apple), (a, avocado), (b, banana), (c, cucumber), (d, dragon fruit) 쌍이 있으면 단일 문자가 키이고 과일이있는 경우 값은 두 개의 버킷이 있습니다. 하나의 버킷은 ValCount가 2이고 코호트는 하나의 키로 만 구성됩니다. 다른 버킷의 ValCount는 1이고 코호트는 3 개의 키 b, c 및 d로 구성됩니다.

이중 연결 버킷 목록은 ValCount에서 주문해야합니다. 시간에 목록의 머리와 꼬리를 찾을 수 있고 이웃을 알면 O ( 1 ) 시간 에 새로운 버킷을 스플 라이스 할 수 있어야합니다. 상상도 못하게 버킷 목록을 BucketList라고합니다.O(1)O(1)

BucketList 외에도 ValueBuckets에 키를 매핑하는 해시 맵인 SetMap이 필요합니다. ValueBucket은 ValueSet (빈 값이 아닌 해시 값 집합)과 버킷에 대한 널이 아닌 포인터로 구성된 쌍입니다. 키 k와 연관된 ValueSet에는 k와 관련된 모든 고유 값이 포함됩니다. ValueSet과 연관된 Bucket 포인터는 ValueSet의 크기와 동일한 코호트를 갖습니다. SetMap에서 키 k와 연관된 Bucket도 BucketList의 키 k와 연관됩니다.

C ++에서 :

struct Bucket {
    unsigned ValCount;
    unordered_set<Key> Cohort;
    Bucket * heavier;
    Bucket * lighter;
};
Bucket * BucketListHead;
Bucket * BucketListTail;

struct ValueBucket {
  unordered_set<Value> ValueSet;
  Bucket * bucket;
};
unordered_map<Key, ValueBucket> SetMap;

최대 빈도 키-값 쌍을 찾으려면 BucketList의 헤드를보고 코호트에서 키를 찾고 SetMap에서 해당 키를 찾은 다음 ValueBucket의 ValueSet에서 값을 찾으면됩니다. (퓨!)

키-값 쌍을 삽입하고 삭제하는 것이 더 까다 롭습니다.

키-값 쌍을 삽입하거나 삭제하려면 먼저 SetMap에 삽입하거나 삭제합니다. 그러면 ValueSet의 크기가 변경되므로 키와 관련된 버킷을 수정해야합니다. 이 변경 사항을 확인하기 위해 살펴볼 버킷은 버킷의 바로 옆에있을 것입니다. 여기에는 몇 가지 사례가 있으며 아마 기뻐할 것입니다. 여전히 문제가있는 경우 자세히 설명합니다.


감사. 실제로 우리는 솔루션에 대한 비슷한 아이디어를 가지고 있었지만 문제가있었습니다. 지금 당장 기억하지 못하는 문제가 무엇인지 확인해야합니다. 다음 주에 더 신중하게 점검하여 솔루션에 발생한 문제를 피할 수 있는지 확인하겠습니다.
Kaveh

내 솔루션에 대해 생각할 수있는 또 다른 방법은 다음과 같습니다.이 경우에는 "비효율적 인"우선 순위 대기열이있는 솔루션 일뿐입니다. 이중으로 연결된 키 버킷 목록으로 구현 된 최대 우선 순위 대기열에는 O (1) insertMin, deleteMax, removeFromBucket 및 증가 키가 있습니다.
jbapple

ValueBuckets의 키에서 매핑을 유지하는 가장 효율적인 방법은 최악의 경우 검색 트리 일 것입니다.
Raphael

라파엘-당신이 무엇을 받고 있는지 잘 모르겠습니다. 해시 테이블이 실제로 비싸거나 최악의 경우 또는 세 번째로 성능이 좋지 않다는 것을 말하고 있습니까?
jbapple

-3

최악의 복잡성

영형(1)

영형(1)

영형(1)

영형(로그로그)

영형()

증명

[0,)선형 공간에서 지원하는 인터넷 ND 분 , 삽입 , 데크 키를 일정 시간 내에, 그리고 삭제 영형(영형 영형 미디엄나는{,}) 시각.

다음의 조합으로 설정됩니다.

레마 3 .τ(n,N) be the delete time for a priority queue for up to n integers in the range [0,N) supporting insert and dec-key in constant time. Then τ(n,N)τ(N,N). This holds whether τ is amortized or worst-case.

and:

THEOREM 6. Theorem 6. We can implement a priority queue that with n integer keys in the range [0,N) in linear space supporting find-min, insert, and dec-key in constant time, and delete in O(1+log log nlog log q) time for a key of rank q.

Reference

Thorup, Mikkel. “Integer Priority Queues with Decrease Key in Constant Time and the Single Source Shortest Paths Problem.” In Proceedings of the Thirty-fifth Annual ACM Symposium on Theory of Computing, 149–158. STOC ’03. New York, NY, USA: ACM, 2003.


Note that in all priority queues it is trivial to move to a structure supporting 'get-min' and 'extract-min' to a structure supporting 'get-max' and 'extract-max'.
A T

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