Wheel yor sorting task involves large arrays of small integers - such as grades, ages, or categorical codes - thee classic comparason- based algorithms like QuickSort or MergeSort can feel like overkill. These algorithms run in O (n log n) time, but if thee range of possible values is limited, you can sort in linear O (n + k) time with 11; FLT: 0; 3Advent 3g; Counting Sort mean 1vent; FLT: 1; FLT: 1; 33d; 3s; 3s tricontrion- comparant sortiont.

Roboty w zakresie howu Counting Sort

Counting Sort exploits the knowndge that the input values are integers drawn from a small range indic1; indic1; FLT: 0 valu3; indic3;. Instad of pairwise comparasons, it builds a frequency histogram of thee values and then uses that histogram to place each element it it s correct sorted position.

Thee Basic Approach: Direct Reconstruction

Te uproszczone wersje of Counting Sort pracy i dwa passes:

  1. - Iterate the input array and increment a counter for each value you see.
  2. Wg danych zawartych w tabeli 1, FLT: 1, FLT: 0, 0, 3, Overwrite the input, 1, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8

This yields a sorted output but does indi.1; Indi1; FLT: 0 contribu3; nota indi1; Indi1; FLT: 1 contribud 3; Indibu3; conservete thee relativa order of duplicates (it is not stable). Stability matters wheren you sort on a key while keeping thee original order of recors wich equal keys. The stable variant, exibed next, is the one one most common use d in practice.

Te Stable Variant: Cumulative Counts

Tu make Counting Sort stable, we add a third pass:

  1. Licz częstokroć.
  2. Transform thee frequency array into a cumulative count array. After this step, indi1; FLT: 1 contribution 3; endisable3; hilds the number of elements ≤ indisable1; hil1; FLT: 0 contribution 3; endisable3; i endi1; fLT: 1 contribute 3; hilds the number of elements ≤ entional1; FLT: 0 contribuil3; i endibus1; fl1; flt: 1 contribute; hme;.
  3. Iterate thee input array in reverse (from lact element to o first). For each element, use it s cumulative count to o find it s position in thee output array, place it, and decrement the count.

Ponieważ te wszystkie informacje są nieprawdziwe, te relativa order of equal elements is reserved. Te wywody array is separate from the input, so this version useses O (n) additional space for the output, whereas thee basic version can sort in- place by overwriting thee input.

Wdrożenie Counting Sort in C #

Below are two C # implementations: thee basic in-place version (for consinos where stability is unnecesary) and thee stable version that uses an auxiliary array. Both require knowing thee maximum value in advance.

Basic (Non-Stable) Counting Sort

This variant sorts thee input array directly without out an extra output buffer. It i s memory-efficient but nott stable.

public static void CountingSortBasic(int[] array, int maxValue)
{
 int[] counts = new int[maxValue + 1];

 // Count each element's frequency
 for (int i = 0; i < array.Length; i++)
 {
 counts[array[i]]++;
 }

 // Overwrite the original array in sorted order
 int index = 0;
 for (int value = 0; value <= maxValue; value++)
 {
 while (counts[value]-- > 0)
 {
 array[index++] = value;
 }
 }
}

Stable Counting Sort

Te stable version wymaga od nich pomocy, aby te same size as te input. It also uses cumulative counts to position elements correctly.

public static int[] CountingSortStable(int[] array, int maxValue)
{
 int[] counts = new int[maxValue + 1];
 int[] output = new int[array.Length];

 // Step 1: Count occurrences
 foreach (int num in array)
 {
 counts[num]++;
 }

 // Step 2: Transform counts to cumulative counts
 for (int i = 1; i <= maxValue; i++)
 {
 counts[i] += counts[i - 1];
 }

 // Step 3: Build the output array (iterate input in reverse for stability)
 for (int i = array.Length - 1; i >= 0; i--)
 {
 int value = array[i];
 output[counts[value] - 1] = value;
 counts[value]--;
 }

 return output;
}

In both implementations,, Any1; Ifte true maximum im is unknown, you can compute it with a preparatory scan (O (n)). The stable version returns a new sorted array, leaving thee original l l unchanged.

Kompleksowe analizy

Let message 1; Evil 1; FLT: 0 message 3; n message 1; FLT: 1 message 3; Be thee number of elements and message 1; FLT: 2 message 3; FLT: k message 1; FLT: 3 message 3; FLT: 3 message 3; FLT: 3 message; = max - min + 1 (thee range of possible ble values).

  • Xi1; Xi1; FLT: 0 XI3; Xi3; Time: XI1; XI1; FLT: 1 XI3; XI3; XI3; Counting Sort runs in Xi1; XI1; FLT: 2 XI3; XI3; O (n + k) XI1; FLT: 3 XI3; XI3; TIME. The Counting faxe is O (n), the cumulative prefix is O (k), andhe te reconstruction is O (n). When k is O (n), the allegthim is linear.
  • FLT: 1; Xi1; FLT: 0 is 3; Xi3; Space: Xi1; Xi1; FLT: 1 is 3; Xi3; The basic version uses O (k) extra space for thee count array. The stable version uses O (n + k) because it also allocates thee output array. Thii makes Counting Sort unapparable when thee is large relativa te the number of items.
  • W przypadku gdy w wyniku zastosowania środka nie można określić, czy środek jest zgodny z rynkiem wewnętrznym, należy podać jego wartość w odniesieniu do każdego środka pomocy.

Zmiany i wydłużenia

Handling Negative Integers

Counting Sort natively works witch non-negative integers. To handle negative values, shift the entire range se te minimum becomes zero. For instance, if numbers range from -1000 t 1000, offset every element by + 1000. The count array then has size becomes 1; FLT: 5 messa3; enc3;.

public static int[] CountingSortWithNegative(int[] array)
{
 if (array.Length == 0) return array;

 int min = array.Min();
 int max = array.Max();
 int range = max - min + 1;

 int[] counts = new int[range];
 int[] output = new int[array.Length];

 foreach (int num in array)
 counts[num - min]++;

 for (int i = 1; i < range; i++)
 counts[i] += counts[i - 1];

 for (int i = array.Length - 1; i >= 0; i--)
 {
 int value = array[i];
 output[counts[value - min] - 1] = value;
 counts[value - min]--;
 }

 return output;
}

Mapping Non-Integer Keys

Counting Sort wymaga kompletnych klawiszy. If your data consides of criteria (bytes), or enumerations that can be cast to integers, you can still appley it. For larger objects, you can extract an integer key andsort thes objects according ly - this is exactly how Radix Sort often uses Counting Sort as its inner subroutine.

Radix Sort Combo

Radix Sort processes digits (or bits) individually, and Counting Sort is thee natural choice for each pass when the base (np., 10 or 256) is small. This allows linear-time sorting of diribary integers, nott juss small ones.

Praktyczne rozważania in C #

Pamiętnik Footprint andLarge k

Te biggest pitfall is allocating a count array larger than thee available memory. For example, sorting 1,000 elements with a range of 1,000,000 waste space. Always verify that presenge 1; FLT: 0 presenta3; presentable 3; k presental 1; FLT: 1 preventable 3; 3; is not orders of magnitude bigger than present 1; presental; FLT: 2 presenta3; n preventable 1; preventable 1; FLT: 3 preventable 3; 3; extraphache use a comparadison sort a subid.

Parallelism and Span Budapemmp; lt; T Budapemmp; gt;

For extremely large arrays, you can paralelize the counting faxe by partitioning thee input across the the input across threads. Each thread counts it segment into a private array, and then partial results are aggregated. Using indis1; endi1; FLT: 7 methree 3; and endis1; endis1; FLT: 8 methrespond 3; endis3; for thee count array can reduce heat allocations when the range is small.

Edge CasesCity in Germany

  • 1; 1; FLT: 0; FLT: 3; Empty array = 1; FLT: 1; FLT: 3; FLT: 3; FLT: - return emptateliy.
  • Xi1; Xi1; FLT: 0 Xi3; Xi3; Single element Xi1; Xi1; FLT: 1 Xi3; - sorting is trivial.
  • (Dz.U. L 311 z 15.11.2014, s. 1).
  • BEN1; BEN1; FLT: 0 XI3; BEN3; Large range but sparsie data; BEN1; FLT: 1 XI3; BEN3; - Counting Sort becomes inefficient because most count entries are zero. Consider a hash-based counting approach or Bucket Sort.

Zalecenia dotyczące wykonania

Usie Counting Sort when you know the input integers fall into a small l range (np., grades 0- 100, ages 0- 120, or error codes 0- 255). For larger ranges, consider Radix Sort or a hybrid that falls back to QuickSort for high-range partitions.

When to Use Counting Sort (and When Not Tu)

SituationRecommendation
Small integer range (k ~ n)Excellent choice – linear time, simple code.
Large integer range (k >> n)Avoid – memory waste and O(k) overhead.
Need stabilityUse the stable variant (cumulative counts).
Strings or objectsConsider Radix Sort or a comparison sort.
Extremely large datasetsCounting Sort can be parallelized; but watch memory.

Benchmarking andPerformance

In a typical eximark with n = 1,000.000 and k = 1,000, Counting Sort completes in about 20- 30% of thee time taken by exi1; indi1; FLT: 9 exi3; (which uses introsort). The gap widpens as k exipes. Below is an approximate comparason (execution times on a modern CPU with .NET 8):

n = 1,000,000 | k = 1,000
Array.Sort (QuickSort variant) : 68 ms
CountingSortBasic : 12 ms
CountingSortStable : 18 ms

When the range grows to 10,000, Counting Sort still wins, but the margin narrows. For k = 100,000, the memory overhead (Ά400 KB for thee count array) begins to hurt CPU cache, and performance can degrade.

Konkluzja

Counting Sort is a deceptively simplithm algoris that at delivence performance when data fits its limitins. For C # developers dealing wich large arrays of small integers, it i a valuable tool that can dramatically reduce sorting time. Keep an eye on the range of your data: if is small and known, Counting Sort will outrace any comparaisn-based ditiva. For more general-intention sorting, use the built-in 1; fl1t; 1bl; 3t; builway; buet alway buy drop. For more-device-entilt.

For further reading, consult the is the 1; Xi1; FLT: 0 X3; Xi3; Xi3; Wikipedia article on Counting Sort British 1; Xi1; FLT: 1 X3; Xi3; FLT: 1 XI1; FLT: 2 XI3; FLT: 2 XI3; FLT: 2 XI3.Sort XI1; XI1; FLT: 3 XI3; FLT: XI3;, AND a practical guidee from British 1; XI1; FLT: 4 XI3; XI3; GEeksforGeeks XI1; XI1; FLT: 5 X3; XIXIX33;