정수 범위를 효율적으로 저장하는 데이터 구조는 무엇입니까?


10

신속하게 다음을 수행 할 수 있도록 0에서 65535 범위의 정수에 컬렉션을 유지해야합니다.

  • 새로운 정수 삽입
  • 연속 정수 범위 삽입
  • 정수 제거
  • 정수 아래의 모든 정수를 제거
  • 정수가 존재하는지 테스트

내 데이터에는 컬렉션에 종종 정수가 포함되어 있습니다. 예를 들어, 특정 시점의 콜렉션은 다음과 같습니다.

{ 121, 122, 123, 124, 3201, 3202, 5897, 8912, 8913, 8914, 18823, 18824, 40891 }

가장 간단한 방법은 C ++ std :: set과 같은 균형 이진 트리를 사용하는 것입니다. 그러나 이것을 사용하면 종종 숫자가 많다는 사실을 활용하지 않습니다. 아마도 범위 모음을 저장하는 것이 더 좋을까요? 그러나 이는 중간에있는 정수가 제거되면 범위를 분할하거나 두 범위 사이의 공간이 채워지면 함께 결합 될 수 있어야 함을 의미합니다.

이 문제에 적합한 기존 데이터 구조가 있습니까?

답변:


9

잎에 간격 (연속 정수 실행)을 포함 할 수 있도록 이진 검색 트리를 사용하는 것이 좋습니다. 간격이 겹치지 않고 순서대로 변하지 않는 것을 유지하십시오 (검색 트리가 변하지 않음). 간격이 겹치지 않는 특수한 경우 간격 트리 또는 세그먼트 트리의 특수한 경우로 간주 될 수 있습니다.

이 데이터 구조는 시간 에 모든 작업을 지원할 수 있습니다 . 여기서 은 간격 수입니다. 우리는 보장하므로 이것이 매우 효율적일 것으로 기대합니다. 특히, 간격을 두 조각으로 나누거나 인접한 두 간격을 시간에 단일 간격으로 병합 할 수 있습니다 .O(lgn)nn65535O(lgn)


5

우선, "빠른"이 그다지 의미가 없기 때문에 다른 이유가 없다면 귀하의 질문은 매우 잘못 표현됩니다. "빠른"의 의미에 대한 몇 가지 메트릭을 제공해야합니다.

그 외에도 문제에 대한 디자인을 만들려고 할 때 먼저 문제를 잘 이해하고 추가 질문을 많이 해야합니다. 이 경우 관련 질문은 (특정 순서가 아닌) 것으로 보입니다.

  • 이 모든 작업이 똑같이 빠르거나 다른 것보다 더 중요해야합니까?
  • 다른 고려 사항이 있습니까?
  • 기억이 전혀 문제가되지 않습니까?
  • 여러 스레드에서 삽입, 제거 및 조회를 수행하는 기능이 문제가됩니까?
  • 작업량은 주로 삽입에 초점을 맞추고 있습니까? 풀이? 올려요?

둘째, 문제 영역이 실제로 라면이 논의는 어리석은 것 같습니다. 똑똑하고 멋진 알고리즘이 정말로 필요한가요? 특히 간단한 배열이 일정한 옵션으로 단일 정수 연산을 다루는 탁월한 옵션 인 경우 선형 시간으로 범위 연산하고 선형 공간이 필요합니까?[0,65535]

조금 더 많은 작업을 위해서는 데이터를 8192 정수의 비트로 저장하여 속도를 희생하면서 공간을 절약 할 수 있습니다. 개념적으로 단일 정수 연산은 여전히 ​​일정 시간이고 범위 정수 연산은 여전히 ​​선형 시간이지만 속도가 느립니다.

따라서 이것이 실제로 문제라면 배열을 사용하고 코드로 다른 더 중요한 것들로 넘어갑니다.

이것이 실제로 문제가 아니며 릴레이하지 않은 다른 고려 사항이있는 경우 (예 : 도메인이 실제로 아니고 문제를 단순화하려고 시도한 경우) 필요한 경우 이번에는 실제 문제를 알려주는 질문을 다시합니다 .[0,65535]


3

Van Emde Boas 트리 와 같은 Integer 데이터 구조를 고려할 수 있습니다 . 정수 데이터 구조는 고정 유니버스 합니다. 언급 한 일부 작업은 매우 효율적으로 구현 될 수 있습니다. 특히 단일 요소 삽입, 삭제 및 요청은 에서 실행됩니다 . 다른 작업 (대량 삽입 / 삭제)은 비용이 더 많이들 수 있지만 Van Emde Boas 트리의 비 트릭을 사용하면 시스템의 단어 크기에 따라 속도를 높일 수 있습니다.O ( log log u )U={0,,u1}O(loglogu)

데이터 구조에 따라 데이터를 저장하는 방법에 대한 영리한 대안이 많이있을 수 있습니다.

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