Sıralanmış bir diziye öğe ekleme


31

Bunu yapmanın en hızlı yolu (algoritmik bir perspektiften ve pratik bir konudan) ne olabilir?

Aşağıdaki satırlar boyunca bir şey düşünüyordum.

Bir dizinin sonuna ekleyebilir ve daha sonra buna yakın olan ve en iyi durumda (en iyi durumda) doğrusal çalışma süresine sahip en iyi durum (başlangıçta tamamen sıralanan dizi) olduğundan bubblesort kullanabilirim.

Öte yandan, sıralanmış bir diziyle başladığımı biliyorsanız, belirli bir öğenin ekleme noktasını bulmak için ikili arama kullanabilirim.

Benim önsezim, ikinci yolun neredeyse optimal olduğu, ama orada ne olduğunu merak ediyorum.

Bu en iyi nasıl yapılabilir?


1
En hızlı yol, sık sık yapmanız gerekiyorsa, en başta bir dizi kullanmamaktır.
reinierpost

Kendi kendine dengeleme ikili ağaç demek istiyorsun?
soandos,

Evet, muhtemelen; cevapları gör ...
reinierpost

Yanıtlar:


25

Okunan ve yazan dizi elemanının sayısını sayarız. Kabarcık sıralama yapmak için tek ihtiyacınız (o zaman, en kötü durumda, iki okur ve iki yazıyor yapmaya sonuna kadar ilk yazma erişimler takaslarını). İkili aramayı yapmak için, ( ikili arama için , en kötü durumda ise dizi öğelerini sağa kaydırmak için , dizi elemanını yazmak için 1n gerekir. onun uygun pozisyonu).n 2 log n + 2 n + 1 2 log n 2 n1+4nn2logn+2n+12logn2n

Dolayısıyla, her iki yöntem de dizi uygulamaları için aynı karmaşıklığa sahiptir, ancak ikili arama yöntemi uzun vadede daha az dizi erişimi gerektirir ... asimptotik olarak, yarısı kadar. Doğal olarak oyunda başka faktörler de var.

Aslında, daha iyi uygulamalar kullanabilir ve yalnızca gerçek dizi erişimlerini satabilirsiniz (eklenecek öğeye erişemez). Sen yapabilirdi sıralama balonu için, ve (akıllı kabarcık kayıt / önbellek erişimi ucuz ve dizi erişim ucundan arama ve yol boyunca değişen, pahalı eğer öyleyse ... İkili arama için yerleştirme için sıralama) daha iyi olabilir, asimptotik olmasa da.günlüğü n + 2 n + 12n+1logn+2n+1

Daha iyi bir çözüm, farklı bir veri yapısı kullanmayı içerebilir. Diziler size O (1) erişimlerini (rastgele erişim) verir, ancak eklemeler ve silme işlemleri maliyetli olabilir. Bir karma tablosunda O (1) ekler ve silmeler olabilir, erişimler maliyetli olur. Diğer seçenekler arasında BST'ler ve yığınlar, vb. Bulunur. Uygulamanızın ekleme, silme ve erişim için kullanım gereksinimlerini göz önünde bulundurarak daha özel bir yapı seçin.

Eklemek istediğiniz takdirde Ayrıca yürütülen sıralanmış bir diziye eleman elemanları, iyi bir fikir verimli sıralama nedeniyle olabilir daha sonra iki dizi birleştirme öğeler; ayrıca, diziler, örneğin yığınlar (yığın sıralaması) kullanılarak verimli bir şekilde oluşturulabilir., n mmnm


1
"Karma tabloda O (1) ekler ve silme olabilir" - genellikle itfa edilir.
Raphael

8
İtfa edilmiş beklenen .
JeffE

BST, arama ve ekleme için (logkipedia) ) 'a sahiptir, peki neden burada en iyi önerilen seçim değil? aramak ve eklemek için. O ( 2 L O g n )O(log n)O(2 log n)
Kashyap

8

Öbek kullanmamak için herhangi bir nedeniniz varsa , Bubble Sort yerine Insertion Sort kullanmayı düşünün . Birkaç sıralanmamış öğeye sahip olmak daha iyidir.


8

O(n)

O(lgn)O(n+lgn)O(n)

O(1)

Her neyse, bu problem için balonları sökmek için bir sebep görmüyorum.


2
O

Keskin olmasından dolayı +1 .. :-)
Kashyap

4

Patrick87 bunu çok iyi açıkladı. Ancak, yapabileceğiniz ek bir optimizasyon, dairesel bir tampon gibi bir şey kullanmak olacaktır: eklenen öğenin konumunun sağındaki öğeleri istediğiniz gibi sağa taşıyabilirsiniz. Ancak öğeleri sola doğru konumun soluna da taşıyabilirsiniz. Bunu yapmak için, diziyi dairesel olarak işlemeniz gerekir, yani son öğe birinciden hemen öncedir ve aynı zamanda öğelerin o anda başladığı yerde kalmanızı da sağlar.

Bunu yaparsanız, dizi erişiminin yarısı kadar yaptığınız anlamına gelebilir (eklediğiniz dizinlerin eşit dağılımını varsayarsak). Konumu bulmak için ikili arama yapılması durumunda, sola mı sağa mı kaydırılacağının seçilmesi önemsizdir. Kabarcık sıralama durumunda, başlamadan önce doğru "tahmin" gerekir. Ancak bunu yapmak basittir: sadece eklenen öğeyi, dizinin medyanıyla karşılaştırın; bu, tek dizi erişiminde yapılabilir.


4

Bu sorun için Ekleme sıralama algoritmasını etkili bir şekilde kullandım . Bir keresinde bir hash table nesnesiyle bir performans sorunumuz vardı, bunun yerine performansı önemli ölçüde artıran ikili arama kullanan yeni bir nesne yazdım. Listeyi sıralı tutmak için, bir arama isteği nedeniyle listenin sıralanması gerektiğinde, en son sıralamaya (yani sıralanmamış parçaların sayısına) eklenmiş olan parçaların sayısını takip eder. sıralanmamış öğelerin yüzdesi. Ekleme sıralamasının kullanılması, performansı artırmada kilit rol oynamıştır.


İtfa edilmiş işletme maliyetleri ile ilgili resmi bir sonucunuz var mı? Ve hoşgeldin!
Raphael
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.