Qual estrutura de dados armazenaria com eficiência intervalos inteiros?

10

Preciso manter uma coleção de números inteiros no intervalo de 0 a 65535 para que eu possa fazer o seguinte rapidamente:

  • Inserir um novo número inteiro
  • Inserir um intervalo de números inteiros contíguos
  • Remover um número inteiro
  • Remova todos os números inteiros abaixo de um número inteiro
  • Teste se um número inteiro está presente

Meus dados têm a propriedade que geralmente contém execuções de números inteiros na coleção. Por exemplo, em algum momento, a coleção pode ser:

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

A abordagem mais simples é apenas usar uma árvore binária balanceada como o C ++ std :: set; no entanto, usando isso, não estou aproveitando o fato de que muitas vezes tenho números. Talvez seja melhor armazenar uma coleção de intervalos? Mas isso significa que um intervalo precisa poder ser dividido se um número inteiro no meio for removido ou unido se o espaço entre dois intervalos for preenchido.

Existe alguma estrutura de dados existente que seria adequada para esse problema?

WilliamKF
fonte

Respostas:

9

Sugiro que você use uma árvore de pesquisa binária, aumentada para que as folhas possam conter um intervalo (uma sequência de números inteiros consecutivos). Mantenha a invariante de que os intervalos não se sobrepõem e estão em ordem (seguindo a invariante da árvore de pesquisa). (Isso pode ser considerado um caso especial de uma árvore de intervalo ou de árvore de segmento, para o caso especial em que os intervalos não se sobrepõem.)

O(lgn)nn65535O(lgn)

DW
fonte
5

Primeiro de tudo, sua pergunta é muito mal formulada, se não por outro motivo, porque "rapidamente" não significa muito. Você precisará fornecer algumas métricas do que "rápido" significa.

Além disso, ao tentar criar um design para um problema, você precisa primeiro entender muito bem o problema e fazer muitas perguntas adicionais . Perguntas relevantes nesse caso parecem ser (em nenhuma ordem específica):

  • Todas essas operações devem ser igualmente rápidas ou são mais importantes que outras?
  • Existem outras considerações?
  • A memória é uma preocupação?
  • A capacidade de executar inserções, remoções e pesquisas de vários threads é uma preocupação?
  • A carga de trabalho está focada principalmente na inserção? Removendo? Olhando pra cima?

[0,65535]

Para um pouco mais de trabalho, você pode economizar espaço, se isso for uma preocupação, às custas da velocidade, armazenando os dados como bits em 8192 números inteiros. Embora conceitualmente as operações com número inteiro único ainda sejam de tempo constante e as operações com número inteiro de distância ainda sejam lineares, elas seriam mais lentas.

Portanto, se esse é realmente o seu problema, eu diria que use uma matriz e vá para outras coisas mais importantes com o código.

[0,65535]

Nik Bougalis
fonte
3

U={0,,u1}O(loglogu)

Dependendo da estrutura dos seus dados, pode haver muitas alternativas inteligentes de como armazenar seus dados.

A.Schulz
fonte