Problema de baza care trebuie inteleasa aici este: complexitatea unui algoritm de sortare e perfect dependenta de multimea de elemente care se sorteaza. Fiind date anumite proprietati speciale se poate reduce cu mult complexitatea algoritmului de sortare. Mai precis:
- pentru o multime fara niciun fel de precizare referitoare la elementele din ea, adica o multime aleatoare, cea mai buna sortare care se poate obtine prin comparatii e de ordinul O(N*lgN) - dupa cum a spus si Morpheus. Atentie, aici se face referire la numere
complet aleatoare, despre care nu se stie nimic altceva.
- pentru multimi cu anumite restrictii / proprietati speciale, se poate reduce cu mult timpul necesar. Sa luam doua exemple:
- pentru un sir de elemente a(1,2*m) care are proprietatea ca prima jumatate a multimii este sortata si cea de-a doua este si ea dar nu neaparat in continuarea primeia, problema se reduce la interclasarea celor doua siruri - adica se va ajunge la O(n)
- acum discutam cazul de fata - cunoscand restrictia ca toate numerele noastre se incadreaza intr-un interval predefinit de forma [a, b] putem crea un vector de elemente v[b-a + 1] in care vom retine, pentru fiecare element, numarul de aparitii. In acest fel, la sfarsit, putem afisa numerele in ordine crescatoare (dupa cum s-a facut si mai sus), rezultand practic vectorul sortat fara niciun fel de comparatie - complexitate: O(n), adica se rezuma la citirea numerelor si incrementarea pozitiei din vector corespunzatoare numarului de aparitii al valorii respectiv. Nu este o sortare "propriu-zisa", dupa cum se prezinta intuitiv o sortare (si anume, folosind comparatii), dar e o solutie paralela care rezolva practic aceasta problema.
Partea dificila din codul oferit de Mihai o constituie macro-ul pe care l-a folosit acolo, #define A (A + 10000). In limbaj matematic, chestia asta s-ar numi abuz de notatie - preprocesorul va avea grija sa inlocuiasca pe A cu A + 10000, care e echivalent cu A[10000] iar in cazul in care am fi avut A[x] ar fi rezultat A[10000 + x], care ar fi rezolvat problema ca vectorul de numarare v este indexat, in "spatiul problemei", de la a la b - in cazul nostru de la -10000 la 10000 - pe cand limbajele C/C++ folosesc indexarea "zero-based" adica pornind de la 0 - practic multimea -10000, -9999, ... , 10000 e mapata catre 0, 1, ..., 20002, dupa care se face artificiul prezentat mai sus - se incrementeaza pozitia din vector corespunzatoare valorii a - adica v[10000 + a] - la fiecare citire a ei. La sfarsit, se vor afisa toate elementele cu numarul de "aparitii" > 0, de un numar de ori egal cu v[10000 + a].
Hope that settles everything