En verimli sabit alan sıralama algoritması nedir?


19

Ben dizi boyutu dışında herhangi bir bayt ayırmaz int diziler için bir sıralama algoritması arıyorum ve iki talimat ile sınırlıdır:

  1. SWAP: sonraki dizini geçerli diziyle değiştirir;

  2. MOVE: imleci +1 veya -1 dizinine taşır;

Yani, dizini değiştirdikten 100sonra komşu olmayan dizinleri değiştiremezsiniz veya dizini değiştiremezsiniz 10. En verimli algoritma nedir - daha az toplam hamle kullanan algoritma?


13
Bu garip değil, sarılmış bir bant kasetine yapıştırılmış arabaların bir listesini sıralayacak fiziksel bir makinedir. Makine, bandı yalnızca ileri veya geri hareket ettirebilir ve yalnızca komşu kartları korse ile değiştirebilir. Gerçek dünyada etrafta ışınlanamazsınız, bu yüzden bunlar kısıtlamalar ...
MaiaVictor

2
Bu nedenle, dizinin boyutu dışında herhangi bir bayt ayırmayan bir algoritma istediğinizi söylediğinizde, sanırım yalnızca öğe depolama alanına başvuruyorsunuz, değil mi? Hala sayaçlar ve benzeri tahsis edebilir miyim?
Mart'ta Darkhogg

5
Tabiiki. Elbette. Bazı ek yapılar ayırabilirsiniz. Hatta tüm diziyi ayırabilir ve çok ağır hesaplama yapabilirsiniz ve bu 0 maliyet olarak sayılır. En aza indirmeniz gereken tek şey, gerçek fiziksel makinenin SWAP / MOVE sayısıdır, çünkü yavaştır. Kabarcık sıralama ben geldim en iyisidir, ama daha iyi seçenekler olması gerektiğini tahmin etti.
MaiaVictor

1
Böyle bir algoritma olduğunu sanmıyorum. Ek bellek olmadan, herhangi bir kontrol durumunu saklamanın bir yolu yoktur.
Raphael

1
@svrm: evet, daha sonra sınırsız RAM ve kaseti RAM'e kopyalama ve üzerinde rasgele hesaplama yapma yeteneği ile, "her şeyi deneyin ve en iyisini uygulayın" algoritması, bandın hareket sayısı açısından en uygunudur. Pratik olması muhtemel değildir, ancak uygulamada çalışma zamanının 0 ,-) değil, yıllarca squilyon olacağı, N uzunluğunda bir kaseti RAM'e kopyalamak için N hamle maliyeti varsa, saf kaba kuvvet optimal olmayabilir, ancak N içinde optimal. Ancak bunların hiçbiri sizin probleminize özgü değildir: bu şekilde ifade edildiğinde birçok sorun sahte bir algoritma kullanılarak "çevrimdışı" çözülebilir.
Steve Jessop

Yanıtlar:


13

Kabarcık türünün çift yönlü bir versiyonu olan kokteyl çalkalayıcı türünü düşünün . Düşükten yükseğe kabarcıklar, ve sonra (bu eklenen bölüm) yüksekten düşüğe kadar kabarcıklar, tamamlanana kadar tekrarlayın. Bu hala , ancak ortalamada önemli ölçüde daha az geçiş yapar, çünkü dizinin yüksek ucuna yakın küçük elemanlar N geçişlerinden ziyade tek bir geçişte son konumlarına taşınacaktır. Ayrıca, bir takasın gerçekleştiği en düşük ve en yüksek konumları takip edebilirsiniz; sonraki geçişlerin bu noktaların ötesine taranmasına gerek yoktur.Ö(n2)


4

Bir dizi sipariş etmek için gereken bitişik öğelerin takas sayısı, dizideki ters çevirme sayısına eşittir. İle , n , toplam elemanları, orada En n * (n-1) / 2 inversiyonu, kabarcık sıralama bu modelde swaplardan asimptotik uygun sayısını verir, böylece.


Aslında, kabarcık sıralaması tam olarak en uygun takas sayısını verecektir. Bununla birlikte, her permütasyon için en uygun takas sayısını yapmanın birkaç yolu vardır ve hangisinin toplam hareket sayısını azalttığı açık değildir. (Kabarcık sıralaması ile "en büyük sıralanmamış seçin ve sıralananın sonuna taşıyın" demek istiyorum)
Peter Kravchuk

4

Ö(n2)

-+

Herhangi bir öğeyi değiştirip değiştirmediğimizi bilmek için bir boole bayrağı kullanmayan algoritma aşağıda verilmiştir (bilgileri bellek yerine makinenin durumunda tutma hilesi):

Start:
    Do until we are not at the leftmost position (Op 4)
        move left (Op 2b)

Check:
    If we are at rightmost position (Op 3)
        goto Finished:
    If current value is larger than next value (Op 5)
        goto Unfinished:
    move right (Op 2a)
    Repeat Check:

Unfinished:
    If we are at rightmost position (Op 3)
        goto Start:
    If current value is larger than next value (Op 5)
        swap the elements (Op 1) and move right (Op 2a)
    Repeat Unfinished:

Finished:
    The list is sorted now, output it.

Eric Lippert'in çözümü, gnome çeşidi de işe yarıyor, çünkü temelde iki yönlü bir kabarcık türüdür.


Ekleme sıralaması ne olacak?
Mart'ta Darkhogg

Kabarcık sıralaması, zaten izin verilenden daha fazla olan en az iki döngü sayacı gerektirir.
Raphael

1
Hayır, sayaç kullanmadan değişiklik (en fazla n kez) olana kadar sola ve sağa, sonra sağdan sola gidebilirsiniz. Bir değişiklik olup olmadığını belirtmek için boole bayrağı için fazladan alana ihtiyacınız yoktur. Bir değişiklik varsa, sadece başka bir alt rutine atlamak dışında, aynı şeyi yapan başka bir alt rutine atlarsınız.
Shreesh

1
Ve elbette, her iki uçta da boş okuyabileceğinizi varsayıyorum, böylece listenin başlangıcı veya sonu olduğunu biliyor olabilirsiniz. Ayrıca, takas etmemiz gerekip gerekmediğini bilmek için hem mevcut hem de sonraki öğeyi okuduğumuzu varsayıyorum.
Shreesh

1
Veya, operatör takasını "artan sırada değilse takas" olarak değiştirirsek.
Shreesh
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.