Menu
Coddy logo textTech

Counting Sort

Son güncelleme

Counting sort, bilinen ve sınırlı bir aralıktaki tam sayılar için karşılaştırmasız bir sıralama yöntemidir. Her değerin kaç kez göründüğünü sayar, ardından bu sayıları kullanarak her değeri doğrudan sıralı konumuna yazar - karşılaştırma gerekmez. Değerlerin sayılıp ardından sıraya yerleştirilişini izlemek için yukarıdan oynat düğmesine basın.

Counting sort O(n + k) sürede çalışır; burada k, giriş değerlerinin aralığıdır. k, n'den çok daha büyük değilse son derece hızlıdır ve O(n log n) karşılaştırmalı sıralamaları geçebilir; ancak değer aralığı çok büyükse O(k) sayım dizisi bunu kullanışsız hale getirir.

Zaman ve alan karmaşıklığı

DurumKarmaşıklıkNotlar
ZamanO(n + k)n eleman, k = değer aralığı
AlanO(n + k)Sayım dizisi + çıktı dizisi
KararlıEvetÖnek toplamları kullanılarak sağdan sola yerleştirildiğinde
Karşılaştırma?HayırKarşılaştırarak değil, sayarak sıralar
En uygunKüçük tam sayı aralığık'nin n'ye yakın olduğu durum

Adım adım

AdımNe olur
1Sayım dizisini boyutlandırmak için en büyük değeri bul.
2Her değerin kaç kez göründüğünü say.
3(İsteğe bağlı) Kararlılık için sayımları önek toplamlarına dönüştür.
4Her değeri, göründüğü sayı kadar çıktıya yaz.
5Çıktı dizisi artık tamamen sıralanmıştır.

Çözümlü örnek

[1, 4, 1, 2, 4] dizisi sıralanıyor (değerler 0 ile 4 arasında olduğundan sayım dizisinde 5 yuva var):

GeçişDurumEylem
Girişi taracount = [0, 2, 1, 0, 2]Oluşumları say: 1 iki kez, 2 bir kez, 4 iki kez görünür.
Önek toplamlarıcount = [0, 2, 3, 3, 5]Her yuva artık indeksinden <= kaç değer olduğunu tutar ve nihai konumları verir.
4'ü yerleştiroutput = [_, _, _, _, 4]Sağdan sola oku: count[4] = 5, bu yüzden 4, 4 indeksine gider; 4'e azalt.
2'yi yerleştiroutput = [_, _, 2, _, 4]count[2] = 3, bu yüzden 2, 2 indeksine gider; 2'ye azalt.
1'i yerleştiroutput = [_, 1, 2, _, 4]count[1] = 2, bu yüzden 1, 1 indeksine gider; 1'e azalt.
4'ü yerleştiroutput = [_, 1, 2, 4, 4]count[4] = 4, bu yüzden bu 4, 3 indeksine gider; 3'e azalt.
1'i yerleştiroutput = [1, 1, 2, 4, 4]count[1] = 1, bu yüzden bu 1, 0 indeksine gider. Dizi sıralanmıştır.

Counting sort ne zaman kullanılır

Şu durumda kullanŞu durumda kaçın
Tam sayıları (veya tam sayıya eşlenebilen anahtarları) küçük ve bilinen bir aralıkta sıralarken.Değer aralığı k, eleman sayısı n'den çok daha büyükken.
Doğrusal O(n + k) zaman gerektiğinde ve ek dizileri karşılayabildiğinde.Bellek kısıtlıyken - sayım dizisi n'den bağımsız olarak O(k) maliyetlidir.
Alt rutin olarak kararlı bir sıralamaya ihtiyacın olduğunda (örneğin radix sort içinde).Anahtarlar float, string veya tam sayıya eşlenemeyen rastgele nesnelerken.
En büyük değer sınırlı ve önceden ucuza hesaplanabilirken.Aralık bilinmiyor veya sınırsızken, dolayısıyla sayım dizisini boyutlandıramazsın.

Counting Sort kodu

Python, JavaScript, Java, C++, C dillerinde temiz ve çalıştırılabilir bir Counting Sort uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.

Python ile Counting Sort kodu

Python
1def counting_sort(a):2    # Works for non-negative integers with a small max value3    counts = [0] * (max(a) + 1)4    for value in a:5        counts[value] += 16    # Prefix sums turn counts into final positions7    for i in range(1, len(counts)):8        counts[i] += counts[i - 1]9    out = [0] * len(a)10    for value in reversed(a):  # reversed keeps equal values stable11        counts[value] -= 112        out[counts[value]] = value13    return out14
15
16nums = [4, 2, 2, 8, 3, 3, 1]17print("Before:", nums)18print("After: ", counting_sort(nums))
Bu kodu Python Playground'da çalıştır

Counting Sort SSS

Counting sort'un zaman karmaşıklığı nedir?
Counting sort O(n + k)'dir; burada n eleman sayısı, k ise olası değerlerin aralığıdır. k = O(n) olduğunda bu doğrusal zamandır. O(n + k) ek alan kullanır.
Counting sort kararlı mıdır?
Olabilir. Kararlı sürüm, sayımların önek toplamlarını oluşturur ve elemanları sağdan sola yerleştirir; bu da eşit anahtarların göreli sırasını korur. Burada gösterilen basit "değere göre yeniden yazma" sürümü doğru bir sıralama üretir ancak genellikle düz tam sayılar için kullanılır.
Counting sort'u ne zaman kullanmalıyım?
Tam sayıları (veya tam sayıya eşlenebilen anahtarları) küçük ve bilinen bir aralıkta sıralarken kullan. Değer aralığı k, eleman sayısından çok daha büyükse sayım dizisi bellek israf eder ve karşılaştırmalı bir sıralama daha iyidir.
Counting sort ile radix sort arasındaki fark nedir?
Counting sort, tek bir geçişte değerin tamamına göre sıralar ve değer aralığı kadar büyük bir sayım dizisine ihtiyaç duyar. Radix sort ise basamak basamak sıralar ve genellikle her basamakta kararlı bir counting sort çağırır; bu da geçiş başına aralığı küçük tutar (örneğin ondalık basamaklar için 10). Radix sort, tek bir counting sort'u kullanışsız kılacak büyük değer aralıklarını yönetir.
Counting sort neden her zaman quicksort'tan hızlı değildir?
Counting sort O(n + k)'dir, bu yüzden yalnızca değer aralığı k, n ile karşılaştırılabilir olduğunda kazanır. k çok büyükse - örneğin 0 ile 1,000,000,000 aralığında 100 değeri sıralamak - O(k) sayım dizisi baskın olur ve bellek israf ederken, quicksort gibi O(n log n) karşılaştırmalı bir sıralama hızlı ve alan açısından verimli kalır.
Counting sort negatif sayıları işleyebilir mi?
Evet, küçük bir kaydırma ile. Sayım dizisini doğrudan değere göre indekslemek yerine value - min ile indeksle; böylece en küçük değer 0 indeksine eşlenir. Sayım dizisinin boyutu max - min + 1 olur. Bu kaydırmayı unutmak, negatif girişlerde hataya yol açan yaygın bir hatadır.
Coddy programming languages illustration

Coddy ile algoritmalarda ustalaş

BAŞLA