Hangi veri yapısı tamsayı aralıklarını etkili bir şekilde depolar?


10

Hızlı bir şekilde aşağıdakileri yapabilmeniz için 0 ile 65535 arasındaki tamsayılar üzerinde bir koleksiyon tutmam gerekiyor:

  • Yeni bir tamsayı ekle
  • Bir dizi bitişik tamsayı ekleme
  • Bir tamsayıyı kaldırma
  • Bir tamsayının altındaki tüm tam sayıları kaldır
  • Bir tamsayı olup olmadığını test edin

Verilerim, koleksiyonda genellikle tamsayılar çalıştırdığı özelliği içeriyor. Örneğin, koleksiyon zamanın bir noktasında olabilir:

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

En basit yaklaşım sadece C ++ std :: set gibi dengeli bir ikili ağaç kullanmaktır, ancak bunu kullanarak, sık sık sayıların olduğu gerçeğinden yararlanmıyorum. Belki bir dizi koleksiyon saklamak daha iyi olur? Ancak bu, bir tamsayı ortadan kaldırılırsa bir aralığın parçalanabilmesi veya iki aralık arasındaki boşluk doldurulduğunda birleştirilmesi gerektiği anlamına gelir.

Bu soruna uygun olabilecek mevcut veri yapıları var mı?

Yanıtlar:


9

Yaprakların bir aralık (ardışık tamsayılar çalışması) içerebilmesi için artırılmış bir ikili arama ağacı kullanmanızı öneririm. Aralıkların üst üste gelmediği ve sıralı olduğu değişmezi koruyun (arama ağacı değişmezini izleyerek). (Bu, aralıkların üst üste gelmediği özel durum için bir aralık ağacının veya bir segment ağacının özel bir durumu olarak düşünülebilir.)

Bu veri yapısı, tüm işlemlerinizi zamanda destekleyebilir, burada aralık sayısıdır. garantili olduğumuz için , bunun oldukça verimli olmasını beklerim. (Özellikle, evet, bir aralığı iki parçaya bölebilir veya iki bitişik aralığı zamanında tek bir aralıkta birleştirebilirsiniz .)n n 65535 O ( lg n )O(lgn)nn65535O(lgn)


5

Her şeyden önce, başka bir nedenden dolayı "çabuk" fazla bir şey ifade etmiyorsa, sorunuz çok kötü ifade edilmiştir. "Hızlı" nın ne anlama geldiğinin bir metriğini sağlamanız gerekir.

Bunun ötesinde, bir sorun için bir tasarım bulmaya çalışırken, öncelikle sorunu çok iyi anlamanız ve birçok ek soru sormanız gerekir . Bu durumda ilgili sorular şu şekilde görünecektir (belirli bir sırayla):

  • Tüm bu işlemler eşit derecede hızlı olmalı mı yoksa bazıları diğerlerinden daha mı önemli?
  • Dikkat edilmesi gereken başka noktalar var mı?
  • Hafıza hiç endişe mi ediyor?
  • Birden çok iş parçacığından ekleme, kaldırma ve arama gerçekleştirme sorunu endişe yaratıyor mu?
  • İş yükü daha çok eklemeye mi odaklanıyor? Çıkarma? Mi arıyorsunuz?

İkinci olarak, sorun alanınız gerçekten ise bu tartışma saçma görünüyor. Akıllı, süslü bir algoritma gerçekten gerekli mi? Özellikle basit bir dizi, tek tamsayı işlemlerini sabit zamanda kapsayan mükemmel bir seçenek olduğunda, lineer zamanda aralık işlemleri ve lineer uzay maliyeti?[0,65535]

Biraz daha fazla çalışma için, eğer bir endişe varsa, veri pahasına 8192 tamsayıda bit olarak saklayarak yerden tasarruf edebilirsiniz. Kavramsal olarak tek tamsayı işlemleri hala sabit zaman ve aralıklı tamsayı işlemleri hala doğrusal zaman olsa da, daha yavaş olacaktır.

Yani, bu gerçekten sizin probleminizse, bir dizi kullanın ve kodla diğer daha önemli şeylere geçin derim.

Bu gerçekten sizin probleminiz değilse ve aktarmadığınız başka hususlar varsa (örneğin, alan adı gerçekten değilse ve sorduğunuz sorunu basitleştirmeye çalışıyorsanız), Sorunuzu tekrar sormak için, bu sefer asıl sorunu bize söyleyin .[0,65535]


3

Van Emde Boas ağacı gibi bir Tamsayı veri yapısı düşünebilirsiniz . Bir Tamsayı veri yapısı sabit bir evrende çalışır . Bahsettiğiniz işlemlerin bazıları çok verimli bir şekilde gerçekleştirilebilir. Özellikle, tek bir eleman eklemek, silmek ve istemek . Diğer işlemler (toplu ekleme / silme) daha maliyetli olabilir, ancak Van Emde Boas ağacındaki bittricks kullanarak sisteminizin kelime boyutuna göre bir hızlanabilmeniz gerekir.O ( günlük kaydı u )U={0,,u1}O(loglogu)

Verilerinizin yapısına bağlı olarak, verilerinizi nasıl saklayacağınız konusunda birçok akıllı alternatif olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.