Bucket sort (bin sort) je stabilní řadicí algoritmus založení na rozdělení vstupního pole do několika částí – takzvaných bucketů (přihrádek) – a seřazení těchto částí pomocí jiného stabilního řadicího algoritmu.
Princip
Bucket sort nejprve rozdělí vstupní pole do několika (disjunktních) přihrádek. Každá přihrádka reprezentuje určitý rozsah vstupních dat – data by měla být v optimálním případě rovnoměrně rozdělena, aby nedocházelo k situaci, kdy je jedna přihrádka přeplněna a další je prázdná. V druhé fázi pak bucket sort zavolá na každou z přihrádek stabilní řadicí algoritmus, případně rekurzivně sám sebe (bucket sort degeneruje na counting sort v případě, že je počet přihrádek stejný jako rozsah dat). Nakonec algoritmus nakopíruje postupně všechny seřazené přihrádky do výstupního pole. Připomeňme si, že pole je seřazeno, protože každá přihrádka pokrývala určitý rozsah a rozsahy se nepřekrývaly.
Asymptotická složitost bucket sortu je , kde
je počet přihrádek,
je velikost vstupního pole a
je složitost vnitřního řadicího algoritmu.
Využití
Bucket sort se dá využít pro řazení obrovských dat, která by nemohl načíst klasický algoritmus najednou. Algoritmus rozdělí vstupní data do dostatečně malých přihrádek a tyto postupně řadí v paměti, zatímco neaktivní přihrádky nechává uložené ve vnější paměti (např. pevný disk). Dalším scénářem využití bucket sortu je distribuované řazení, při kterém je každá přihrádka řazena v jiném vlákně, připadně dokonce na jiném stroji.
Kód
01.
/**
02.
* Bucket sort
03.
* @param array pole k serazeni
04.
* @param bucketCount pocet bucketu
05.
* @return serazene pole (od nejmensiho k nejvyssimu)
06.
*/
07.
public
static
int
[] bucketSort(
int
[] array,
int
bucketCount) {
08.
if
(bucketCount <=
0
)
throw
new
IllegalArgumentException(
"Neplatny pocet bucketu"
);
09.
if
(array.length <=
1
)
return
array;
//trivialne serazeno
10.
11.
int
high = array[
0
];
12.
int
low = array[
0
];
13.
for
(
int
i =
1
; i < array.length; i++) {
//najdeme nejvyssi a nejnizsi
14.
if
(array[i] > high) high = array[i];
15.
if
(array[i] < low) low = array[i];
16.
}
17.
double
interval = ((
double
)(high - low +
1
))/bucketCount;
//pocet cisel krytych jednim bucketem = pocet_cisel_celkem/pocet_bucketu
18.
19.
ArrayList<Integer> buckets[] =
new
ArrayList[bucketCount];
20.
for
(
int
i =
0
; i < bucketCount; i++) {
//inicializace bucketu
21.
buckets[i] =
new
ArrayList();
22.
}
23.
24.
for
(
int
i =
0
; i < array.length; i++) {
//rozhozeni cisel do bucketu
25.
buckets[(
int
)((array[i] - low)/interval)].add(array[i]);
26.
}
27.
28.
int
pointer =
0
;
29.
for
(
int
i =
0
; i < buckets.length; i++) {
30.
Collections.sort(buckets[i]);
//mergeSort
31.
for
(
int
j =
0
; j < buckets[i].size(); j++) {
//sesypat zpet
32.
array[pointer] = buckets[i].get(j);
33.
pointer++;
34.
}
35.
}
36.
return
array;
37.
}