Serwis Edukacyjny
Nauczycieli

w I-LO w Tarnowie
obrazek Materiały głownie dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

Autor artykułu: mgr Jerzy Wałaszek

©2026 mgr Jerzy Wałaszek

Sortowanie Pozycyjne
 Radix Sort

SPIS TREŚCI
Podrozdziały

Algorytm

Pozycją (ang. radix) nazywamy miejsce cyfry w zapisie liczby. Sortowanie pozycyjne polega na sortowaniu elementów wg kolejnych (licząc od końca) cyfr liczby. Algorytm sortujący musi być stabilny, tzn. nie może zmieniać kolejności elementów równych, w przeciwnym razie efekty poprzednich sortowań zostaną utracone.

Przykład:

Posortować algorytmem sortowania pozycyjnego zbiór liczb:

{ 547 398 247 153 121 792 421 }

Liczby posortujemy wg kolejnych od końca cyfr:

start ??x ?x? x?? koniec
547
398
247
153
121
792
421
121
421
792
153
547
247
398
121
421
547
247
153
792
398
121
153
247
398
421
547
792
121
153
247
398
421
547
792

Po posortowaniu ostatniej cyfry liczby tworzą ciąg posortowany.

Sortowanie wg poszczególnych cyfr możemy przeprowadzić w czasie liniowym. Operację musimy wykonać tyle razy, z ilu cyfr zbudowane są liczby reprezentujące sortowane elementy. Jeśli liczby są równomiernie rozłożone w reprezentowanym zbiorze, to n elementów może mieć do (logpn + 1) cyfr, gdzie p jest podstawą systemu zapisu liczb. Zatem czas sortowania będzie proporcjonalny do iloczynu n(logpn + 1). Klasa złożoności obliczeniowej jest równa O(n log n).

Przykład:

Posortować algorytmem sortowania pozycyjnego zbiór liczb binarnych:

{100111 111011 011101 101011 001111 101000 110011 100001 101101 111111 000011}
start   koniec
100111
111011
011101
101011
001111
101000
110011
100001
101101
111111
000011
101000
100111
111011
011101
101011
001111
110011
100001
101101
111111
000011
101000
011101
100001
101101
100111
111011
101011
001111
110011
111111
000011
101000
100001
111011
101011
110011
000011
011101
101101
100111
001111
111111
100001
110011
000011
100111
101000
111011
101011
011101
101101
001111
111111
100001
000011
100111
101000
101011
101101
001111
110011
111011
011101
111111
000011
001111
011101
100001
100111
101000
101011
101101
110011
111011
111111
000011
001111
011101
100001
100111
101000
101011
101101
110011
111011
111111

Sortowanie wg bitów jest bardzo proste, jednakże mało efektywne. Lepszym rozwiązaniem jest przyjęcie za podstawę p liczby będącej potęgą 2, np. 24 lub 28. W takim przypadku sortujemy wg grup bitów (dla 24 - grupy 4 bitów, dla 28 - grupy 8 bitów). Zgodnie z podanym wcześniej wzorem klasa czasowej złożoności obliczeniowej będzie równa:

dla p = 24 :  O(n log16 n)
dla p = 28 :  O(n log256 n)

Oba wzory sprowadzają się do O(n log n) (udowodnij to), lecz sortowanie wykonywane jest odpowiednio 4 i 8 razy szybciej (mniejsze współczynniki proporcjonalności c).

Jako algorytm sortujący idealnie pasuje opisany w poprzednim rozdziale algorytm sortowania przez zliczanie.


do podrozdziału  do strony 

Opis algorytmu

Specyfikacja problemu

Dane wejściowe

n - liczba elementów w sortowanym zbiorze, n ∈ N
d[ ] - sortowany zbiór danych. Indeksy elementów rozpoczynają się od wartości 1.
MAXel - maksymalna wartość sortowanych elementów

Dane wyjściowe

d[ ] - posortowany rosnąco zbiór danych

Zmienne pomocnicze

b[ ] - pomocniczy zbiór danych. Indeksy elementów rozpoczynają się od 1.
m - maska bitowa do wydzielania bitu z elementu, m ∈ N
i - zmienna sterująca pętli, i ∈ N
L0 - licznik bitów 0, L0 ∈ N
L1 - licznik bitów 1, L1 ∈ N

Lista kroków

Sortuj(z1[ ], z2[ ], m)

K01: L0 ← 0;  L1 ← 0
K02: Dla i = 1,2,...,n:
    wykonuj krok K03
K03:     Jeśli z1[i] ∧ m ≠ 0,
    to L1 ← L1 + 1
    inaczej L0 ← L0 + 1
K04: L1 ← L1 + L0
K05: Dla i = n, n  - 1,...,1:
    wykonuj krok K06
K06:     Jeśli z1[i] ∧ m ≠ 0,
    to z2[L1] ← z1[i];  L1 ← L1 - 1
    inaczej z2[L0] ← z1[i];  L0 ← L0 - 1
K07: Zakończ

Główny algorytm sortowania pozycyjnego

K01: m ← 1
K02: Dopóki m  ≤ MAXel:
    wykonuj kroki
K03...K06
K03:     Sortuj(d[ ], b[ ], m)
K04:     Przesuń bity maski m o jeden w lewo
K05:     Sortuj(b[ ], d[ ], m)
K06:     Przesuń bity maski m o jeden w lewo
K07: Zakończ

Schemat blokowy

obrazek

Zasada pracy algorytmu sortowania pozycyjnego jest bardzo prosta. Ustawiamy maskę bitową m, tak aby bit b0  miał wartość 1. Następnie w pętli warunkowej wywołujemy procedurę sortowania przez zliczanie przekazując jej jako parametry sortowany zbiór danych d[ ] oraz zbiór pomocniczy b[ ], w którym znajdzie się wynik sortowania, i maskę m. Przesuwamy bity maski o jeden w lewo. Jeszcze raz wywołujemy procedurę sortującą (zwróć uwagę na zamienioną kolejność zbiorów - sortowany jest b[ ], a wynik trafia z powrotem do d[ ]) i przesuwamy bity maski o jeden w lewo.

Procedura sortująca działa wg opisanego w poprzednim rozdziale algorytmu sortowania przez zliczanie:

Zerujemy liczniki bitu 0 oraz bitu 1. W pierwszej pętli zliczamy bity 0 i 1. Następnie obliczamy ostatnie pozycje dla elementów zawierających odpowiednio bit 0 i bit 1. Przepisujemy elementy ze zbioru wejściowego na odpowiadające im  pozycje w zbiorze wyjściowym.


do podrozdziału  do strony 

Przykładowe programy

C++
// Sortowanie Pozycyjne
//---------------------
// (C)2012 mgr Jerzy Wałaszek
// I Liceum Ogólnokształcące
// w Tarnowie

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <time.h>

using namespace std;

// ilość elementów
const int N = 160;
// maksymalna wartość elementu
const int MAXEL = 999;

// Procedura sortująca
void Sortuj(unsigned z1[],
            unsigned z2[],
            unsigned m)
{
  unsigned L[2],i;

  L[0] = L[1] = 0;
  for(i = 1; i <= N; i++)
    L[(z1[i] & m) > 0]++;
  L[1] += L[0];
  for(i = N; i >= 1; i--)
   z2[L[(z1[i] & m) > 0]--] = z1[i];
}

int main()
{
  unsigned d[N+1],b[N+1],i,m;

  cout << " Sortowanie pozycyjne\n"
          "----------------------\n"
          "(C)2005 Jerzy Walaszek\n\n"
          "Przed sortowaniem:\n\n";

  // Generujemy pseudolosową
  // zawartość zbioru d[]
  srand((unsigned)time(NULL));
  for(i = 1; i <= N; i++)
  {
    d[i] = rand() % (MAXEL + 1);
    cout << setw(4) << d[i];
  }
  cout << endl << endl;

  // Ustawiamy maskę na najmłodszy bit
  m = 1;

  // Sortujemy
  while(m <= MAXEL)
  {
    Sortuj(d,b,m); m <<= 1;
    Sortuj(b,d,m); m <<= 1;
  }

  // Wyświetlamy wyniki
  cout << "Po sortowaniu:\n\n";
  for(i = 1; i <= N; i++)
    cout << setw(4) << d[i];
  cout << endl << endl;
  system("pause");
  return 0;
}
Pascal
// Sortowanie Pozycyjne
//---------------------
// (C)2012 mgr Jerzy Wałaszek
// I Liceum Ogólnokształcące
// w Tarnowie

program RadixSort;

const
  // ilość elementów
  N = 160;
  // maksymalna wartość elementu
  MAXEL = 999;

type
  TZbior = array[1..N] of cardinal;

// Procedura sortująca
procedure Sortuj(var z1,z2 : TZbior;
                     m : cardinal);
var
  L : array[boolean] of cardinal;
  i : cardinal;
  t : boolean;
begin
  L[false] := 0; L[true] := 0;
  for i := 1 to N do
    inc(L[(z1[i] and m) > 0]);
  inc(L[true], L[false]);
  for i := N downto 1 do
  begin
    t := (z1[i] and m) > 0;
    z2[L[t]] := z1[i];
    dec(L[t]);
  end;
end;

var
  d,b : TZbior;
  i   : integer;
  m   : cardinal;

begin
  writeln(' Sortowanie pozycyjne');
  writeln('----------------------');
  writeln('(C)2005 Jerzy Walaszek');
  writeln;

  // Generujemy pseudolosową
  // zawartość zbioru d[]
  randomize;
  for i := 1 to N do
    d[i] := random(MAXEL + 1);
  writeln('Przed sortowaniem:');
  writeln;
  for i := 1 to N do
    write(d[i]:4);
  writeln;
  writeln;

  // Ustawiamy maskę na najmłodszy bit
  m := 1;

  // Sortujemy
  while m <= MAXEL do
  begin
    Sortuj(d,b,m);
    m := m shl 1;
    Sortuj(b,d,m);
    m := m shl 1;
  end;

  // Wyświetlamy wyniki
  writeln('Po sortowaniu:');
  writeln;
  for i := 1 to N do
    write(d[i]:4);
  writeln;
  writeln;
  writeln('Nacisnij Enter...');
  readln;
end.
Basic
' Sortowanie Pozycyjne
'---------------------
' (C)2012 mgr Jerzy Wałaszek
' I Liceum Ogólnokształcące
' w Tarnowie

' ilość elementów
CONST N = 160
' maksymalna wartość elementu
CONST MAXEL = 999

' Procedura sortująca
DECLARE SUB Sortuj(z1() AS UINTEGER, _
                   z2() AS UINTEGER, _
                   BYVAL m AS UINTEGER)
                   
SUB Sortuj(z1() AS UINTEGER, _
           z2() AS UINTEGER, _
           BYVAL m AS UINTEGER)

  DIM AS UINTEGER L0,L1,i
  
  L0 = 0: L1 = 0
  FOR i = 1 TO N
    IF (z1(i) AND m) > 0 THEN
      L1 += 1
    ELSE
      L0 += 1
    END IF
  NEXT
  L1 += L0
  FOR i = N TO 1 STEP -1
    IF (z1(i) AND m) > 0 THEN
      z2(L1) = z1(i)
      L1 -= 1
    ELSE
      z2(L0) = z1(i)
      L0 -= 1
    END IF
  NEXT
END SUB

DIM AS UINTEGER d(N),b(N),i,m

PRINT " Sortowanie pozycyjne"
PRINT "----------------------"
PRINT "(C)2005 Jerzy Walaszek"
PRINT

' Generujemy pseudolosową
' zawartość zbioru d()

RANDOMIZE
FOR i = 1 TO N
  d(i) = INT(RND(1) * (MAXEL + 1))
NEXT
PRINT "Przed sortowaniem:"
PRINT
FOR i = 1 TO N
  PRINT USING "####"; d(i);
NEXT
PRINT
PRINT

' Ustawiamy maskę na najmłodszy bit
m = 1

' Sortujemy
WHILE m <= MAXEL
  Sortuj(d(),b(),m)
  m = m SHL 1
  Sortuj(b(),d(),m)
  m = m SHL 1
WEND

' Wyświetlamy wyniki
PRINT "Po sortowaniu:"
PRINT
FOR i = 1 TO N
  PRINT USING "####"; d(i);
NEXT
PRINT
PRINT
PRINT "Nacisnij dowolny klawisz..."
SLEEP
END
Python (dodatek)
# Sortowanie Pozycyjne
#---------------------
# (C)2026 mgr Jerzy Wałaszek
# I Liceum Ogólnokształcące
# w Tarnowie

import random

# ilość elementów
n = 160
# maksymalna wartość elementu
maxel = 999

# Procedura sortująca
def sortuj(z1,z2,m):
    l = [0,0]
    for i in range(1,n+1):
        l[(z1[i] & m) > 0] += 1
    l[1] += l[0]
    for i in reversed(range(1,n+1)):
        z2[l[(z1[i] & m) > 0]] = z1[i]
        l[(z1[i] & m) > 0] -= 1

d = [random.randrange(maxel+1) for _ in range(n+1)]
b = [0] * (n + 1)

print(" Sortowanie pozycyjne")
print("----------------------")
print("(C)2026 Jerzy Wałaszek")
print()
print("Przed sortowaniem:")
print()

for i in range(1,n + 1):
    print("%4d" % d[i],end="")
print()
print()

# Ustawiamy maskę na najmłodszy bit
m = 1

# Sortujemy
while m <= maxel:
    sortuj(d,b,m)
    m <<= 1
    sortuj(b,d,m)
    m <<= 1

# Wyświetlamy wyniki
print("Po sortowaniu:")
print()
for i in range(1,n + 1):
    print("%4d" % d[i], end="")
print()
print()
input("Naciśnij Enter...")
Wynik:
 Sortowanie pozycyjne
----------------------
(C)2026 Jerzy Wałaszek

Przed sortowaniem:

 357 913 949 916 894  21 229 986 229 983 919 662 160 431 772 289  57 906 163 113
 912 192 227  94 448 938 487 699 278 981 827 789 526 574 869 164  49 104 870 908
 215 541 694 780 312 910 286  39 220 617 898 697 409 487 838 687 468 725 976 256
 410 710 137 554 154  70 197  93  27 396 322 113 319 875 815  56 145 504 405 549
 456 776 694 848 233 339 969  96 123 533 531  31  78 812 403  80 209 554  18 928
 946 805 835  42 314 795  61 386 959 565 942 897 907  19  42 302 955  66 428 843
 560 409 907 489 987 110 347 888 498 663 731 544 262 557 511 817 950 765 723 242
 680 514 267 776 944 261 867 151 615 904 118 956 459 632 347 301 970 439 391 232

Po sortowaniu:

  18  19  21  27  31  39  42  42  49  56  57  61  66  70  78  80  93  94  96 104
 110 113 113 118 123 137 145 151 154 160 163 164 192 197 209 215 220 227 229 229
 232 233 242 256 261 262 267 278 286 289 301 302 312 314 319 322 339 347 347 357
 386 391 396 403 405 409 409 410 428 431 439 448 456 459 468 487 487 489 498 504
 511 514 526 531 533 541 544 549 554 554 557 560 565 574 615 617 632 662 663 680
 687 694 694 697 699 710 723 725 731 765 772 776 776 780 789 795 805 812 815 817
 827 835 838 843 848 867 869 870 875 888 894 897 898 904 906 907 907 908 910 912
 913 916 919 928 938 942 944 946 949 950 955 956 959 969 970 976 981 983 986 987

Naciśnij Enter...
JavaScript
<html>
  <head>
  </head>
  <body>
    <form style="BORDER-RIGHT: #ff9933 1px outset;
                 PADDING-RIGHT: 4px; BORDER-TOP: #ff9933 1px outset;
                 PADDING-LEFT: 4px; PADDING-BOTTOM: 1px;
                 BORDER-LEFT: #ff9933 1px outset; PADDING-TOP: 1px;
                 BORDER-BOTTOM: #ff9933 1px outset;
                 BACKGROUND-COLOR: #ffcc66" name="frmradixsort">
      <h3 style="text-align: center">Sortowanie Pozycyjne</h3>
      <p style="TEXT-ALIGN: center">
        (C)2012 mgr Jerzy Wałaszek - I LO w Tarnowie
      </p>
      <hr>
      <p style="TEXT-ALIGN: center">
        <input onclick="main()" type="button" value="Sortuj" name="B1">
      </p>
      <p id="t_out" style="TEXT-ALIGN: center">...</p>
    </form>

<script language=javascript>

// Sortowanie Pozycyjne
//--------------------------------------------------------
// (C)2012 mgr Jerzy Wałaszek
// I Liceum Ogólnokształcące
// im. K. Brodzińskiego
// w Tarnowie
//--------------------------------------------------------

var N     =  80; // ilość elementów
var MAXEL = 999; // maksymalna wartość elementu

// Procedura sortująca

function Sortuj(z1,z2,m)
{
  var L0,L1,i;

  L0 = L1 = 0;
  for(i = 1; i <= N; i++) if((z1[i] & m) > 0) L1++; else L0++;
  L1 += L0;
  for(i = N; i >= 1; i--)
    if((z1[i] & m) > 0) z2[L1--] = z1[i]; else z2[L0--] = z1[i]; 
}

function main()
{
  var d = new Array(N + 1);
  var b = new Array(N + 1);
  var i,m,t;

  t = "Przed sortowaniem:<BR><BR>";

// Generujemy pseudolosową zawartość zbioru d[ ]

  for(i = 1; i <= N; i++)
  {
    d[i] = Math.floor(Math.random() *(MAXEL + 1));
    t += " " + d[i];
  }

// Ustawiamy maskę na najmłodszy bit

  m = 1;

// Sortujemy

  while(m <= MAXEL)
  {
    Sortuj(d,b,m); m <<= 1;
    Sortuj(b,d,m); m <<= 1;
  }

// Wyświetlamy wyniki

  t += "<BR><BR>Po sortowaniu:<BR><BR>";
  for(i = 1; i <= N; i++) t += " " + d[i];
  document.getElementById("t_out").innerHTML = t;
}

</script> 

  </body>
</html>

Sortowanie Pozycyjne

(C)2012 mgr Jerzy Wałaszek - I LO w Tarnowie


...


do podrozdziału  do strony 

Zobacz również na: Sortowanie rozrzutowe | Sortowanie kubełkowe 1 | Listy | Sortowanie kubełkowe 2 | Sortowanie przez zliczanie

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2026 mgr Jerzy Wałaszek

Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.

Informacje dodatkowe.