Sıralanmamış dizinin ortancasını


45

Sıralanmamış bir dizinin medyanını bulmak için, n elementleri için zamanında bir min-yığın yapabiliriz ve sonra medyanı elde etmek için birer birer n / 2 elementi çıkarabiliriz . Ancak bu yaklaşım O ( n log n ) zaman alacaktır .Ö(ngünlükn)nn/2Ö(ngünlükn)

Aynı şeyi zamanında bazı yöntemlerle yapabilir miyiz ? Yapabilirsek, o zaman nasıl?Ö(n)



1
@JukkaSuomela Neden bu kadar hızlı ve basit bir cevap vermiyorsunuz (ideal olarak böyle bir algoritmanın kısa bir açıklaması ile)?
Raphael

2
Not ilgili meta tartışma ; Anlaşıldığı kadarıyla basit web aramaları bu sorunun cevabını veriyor.
Raphael

Yanıtlar:


45

Bu özel bir durumdur seçim algoritması bulabilirsiniz ile bir dizinin en küçük elemanı inci k dizinin boyutunun yarısıdır. En kötü durumda doğrusal olan bir uygulama var.kk

Genel seçim algoritması

İlk edelim bir algoritma bakın find-kthbulur bir dizinin inci en küçük elemanı:k

find-kth(A, k)
  pivot = random element of A
  (L, R) = split(A, pivot)
  if k = |L|+1, return pivot
  if k ≤ |L|  , return find-kth(L, k)
  if k > |L|+1, return find-kth(R, k-(|L|+1))

İşlev , içindeki tüm öğelerin diğerlerinden ve hepsinden büyük olacak şekilde split(A, pivot)döndürür (eksi bir oluşumuL,RRpivotLpivot ). Sonra her şey yinelemeli olarak yapılır.

Bu , ortalama ancak O ( n, 2 ) , en kötü durumda.Ö(n)Ö(n2)

Doğrusal en kötü durum: medyan medyan algoritması

Daha iyi bir pivot, Abu medyanlar dizisi üzerinde prosedürü çağırarak, 5 büyüklüğündeki alt dizilerin tüm medyanlarının medyanıdır.

find-kth(A, k)
  B = [median(A[1], .., A[5]), median(A[6], .., A[10]), ..]
  pivot = find-kth(B, |B|/2)
  ...

Bu , her durumda garanti eder . Bu açık değil. Bu powerpoint slaytları hem algoritmayı hem de karmaşıklığı açıklamada yardımcı olur.Ö(n)

Rasgele bir pivot kullanarak çoğu zaman daha hızlı olduğunu unutmayın.


Bu boyut 5standart mı? A boyutu 5'ten küçükse ne olur?
Jayesh,

Herhangi bir sabit n için, sonsuz olmadıkça, karmaşıklık sabittir. Bu nedenle, O (2 ^ n) olsa bile, bu özel durum için sonlu karmaşıklığı olan herhangi bir geçerli algoritma kullanabilirsiniz. Sabit bir n için (yani en fazla 4 dışarıda), karmaşıklık en fazla O (2 ^ 4) = O (1) 'dir.
v6ak

3
İlk algoritmada: return A[k]yanlıştır ( Aalgoritmayı tartışmaya sokacak şekilde sıralanmadıkça). Eğer splitbölmek oldu A, öyle ki k = |L| + 1nerede hala bilmiyorum kinci elemanıdır. Temel durumunuz, |A| = 1başka iki özyinelemeli aramadan birini yapmanız gerektiğinde.
wcochran

2
@NickCaplinger, web.archive.org'u kullanarak düzeltildi
jmad

1
Genel seçim algoritması O (NlogN) için en kötü durum değil mi? Hatta her aramadan sonra dizinin sadece% 10 özyinelemeli çağrı yaprakları, o zaman esas 10. yılında bir logaritma hala
octavian

6

n-1/4Ö(n) algoritmasından ve doğrusal çalışma süresinde daha küçük bir sabit faktör oluşturur.

Algoritma ana fikri örnekleme kullanmaktır. Dizinin sıralanmış düzeninde birbirine yakın olan ve bunlar arasında medyan bulunan iki öğe bulmalıyız. Tam bir tartışma için referansa [MU2017] bakın.


[MU2017] Michael Mitzenmacher ve Eli Upfal. "Olasılık ve Hesaplama: Algoritma ve Veri Analizinde Rastgele ve olasılıksal Teknikler", bölüm 3, sayfa 57-62. Cambridge University Press, İkinci baskı, 2017.

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.