Lista 3, Zadanie 8

by Jerry Sky



Problem

Potrzebujemy algorytmu do sortowania nn liczb całkowitych z przedziału od 11 do n2n^2 w czasie O(n)O(n).

Concept

Użyjemy tutaj algorytmu RadixSort do podzielenia liczb na części które sortujemy dalej przy pomocy algorytmu CountingSort.

Przy czym, wybór sposobu podziału jest istotny podczas naszego „dzielenia liczb na części”. Zależy nam na złożoności O(n)O(n), więc najlepiej przejść z bazy dziesiętnej na bazę nn.
Wówczas CountingSort zostanie użyty tylko dwa razy, jako że mamy tylko n2n^2 liczb do posortowania o postaci (ab)n(\overline{ab})_n, gdzie a,ba,b to cyfry liczby w bazie nn.

Oczywiście tutaj pojawia się problem liczby n2n^2 która wykracza poza ten zakres, ponieważ ma postać (100)n(100)_n.
Rozwiązaniem może być wprowadzenie specjalnego przypadku dla tej liczby, jako że jest to max\maximum rozważanego przedziału. Możemy wtedy instancje takich liczb przesuwać na sam koniec posortowanej listy.
Innym rozwiązaniem tutaj może być przesunięcie wszystkich elementów o 11 lokalnie, na czas sortowania. Wówczas mielibyśmy liczby z zakresu [0,n21][0,n^2-1] które jak najbardziej da się zapisać w formacie (ab)n(\overline{ab})_n.

W rozwiązaniu rozważymy algorytm przesuwający liczby o 11 żeby zmieściły się w zakresie [0,n21][0,n^2-1].

Rozwiązanie

Pseudokod

CustomSort:
input : AA - lista nn liczb z przedziału [1,n2][1,n^2]
output: posortowana lista AA'

  1. e=1e = 1
  2. while e<n2e < n^2
    1. count[n]count[n]
    2. i=0i=0
    3. while i<ni<n
      1. count[ A[i]1emodn ]count\left[~\lfloor \frac{A[i]-1}{e} \rfloor\mod n~\right]++
      2. ii++
    4. i=1i=1
    5. while i<ni<n
      1. count[i]=count[i1]count[i] = count[i-1]
      2. ii++
    6. tmp[n]tmp[n]
    7. i=n1i=n-1
    8. while i0i\ge0
      1. tmp[count[A[i]1emodn]1]=A[i]tmp\left[count\left[\lfloor \frac{A[i]-1}{e} \rfloor\mod n\right]-1\right] = A[i]
      2. count[A[i]1emodn]count\left[\lfloor \frac{A[i]-1}{e} \rfloor\mod n\right]--
      3. ii--
    9. i=0i=0
    10. while i<ni<n
    11. A[i]=tmp[i]A[i] = tmp[i]
    12. ii++
    13. e=ene = e\cdot n

Opis pseudokodu