Bubble sort (bublinkové řazení) je jednoduchý
stabilní řadící algoritmem se složitostí . Vylepšením bubble sortu je shakersort (oboustranný
bubble sort).
Princip
Pokud si představíme řazená čísla jako bublinky, tak ty s menší hodnotou jsou lehčí než ty s vyšší hodnotou a stoupají proto ve vodě rychleji.
Obdobně postupuje také bubble sort. Porovnává dva sousední prvky, a pokud je nižší číslo nalevo od vyššího, tak je prohodí (nižší číslo je lehčí a rychleji stoupá ke konci pole) a se stejnou logikou pokračuje na dalším indexu. Pokud jsou čísla ve správném pořadí, tak je neprohodí – pouze postoupí dále (algoritmus tím našel lehčí bublinku). Na konci iterace se tímto způsobem na konec pole vždy dostane ta nejlehčí bublinka (nejnižší číslo). Nyní algoritmus můžeme pustit znovu na redukovaný problém (na poslední pozici pole je již to správné číslo).
Po n-1 průchodech (poslední bublinka je seřazena triviálně) je pole seřazeno.
Vizualizace
Příklad
(3 2 8 7 6) // 3 a 2 jsou v korektním pořadí, posuňme se o index
(3 2 8 7 6) // 8 > 2, prohoďme je
(3 8 2 7 6) // 7 > 2, prohoďme je (zde je vidět probublávání nejlehčí dvojky vzhůru)
(3 8 7 2 6) // 6 > 2, prohoďme je
(3 8 7 6 2) // nový průchod polem: na posledním místě je nejlehčí prvek, tudíž se nám řazená úloha o jedna zkrátila, 8 > 3, prohoďme je
(8 3 7 6 2) // 7 > 3, prohoďme je
(8 7 3 6 2) // 6 > 3, prohoďme je
(8 7 6 3 2) // seřazeno
Kód
1.
function bubbleSort(array a)
2.
for
i in
1
-> a.length -
1
do
3.
for
j in
1
-> a.length - i -
1
do
4.
if
a[j] < a[j+
1
]
5.
prohoď(a[j], a[j+
1
]);
01.
/**
02.
* Bublinkove razeni (od nejvyssiho)
03.
* @param array pole k serazeni
04.
*/
05.
public
static
void
bubbleSort(
int
[] array){
06.
for
(
int
i =
0
; i < array.length -
1
; i++) {
07.
for
(
int
j =
0
; j < array.length - i -
1
; j++) {
08.
if
(array[j] < array[j+
1
]){
09.
int
tmp = array[j];
10.
array[j] = array[j+
1
];
11.
array[j+
1
] = tmp;
12.
}
13.
}
14.
}
15.
}
01.
/**
02.
* Bublinkove razeni (od nejmensiho)
03.
* @param array pole k serazeni
04.
* @param size velikost pole
05.
*/
06.
void
bubbleSort(
int
* array,
int
size){
07.
for
(
int
i = 0; i < size - 1; i++){
08.
for
(
int
j = 0; j < size - i - 1; j++){
09.
if
(array[j+1] < array[j]){
10.
int
tmp = array[j + 1];
11.
array[j + 1] = array[j];
12.
array[j] = tmp;
13.
}
14.
}
15.
}
16.
}
01.
/**
02.
* Bublinove razeni (od nejmensiho po nejvetsiho)
03.
* @param arr pole k serazeni
04.
* @author Thomas (www.adamjak.net)
05.
*/
06.
static
void
BubbleSort(
int
[] arr)
07.
{
08.
for
(
int
i = 0; i < arr.Length - 1; i++)
09.
{
10.
for
(
int
j = 0; j < arr.Length - i - 1; j++)
11.
{
12.
if
(arr[j + 1] < arr[j])
13.
{
14.
int
tmp = arr[j + 1];
15.
arr[j + 1] = arr[j];
16.
arr[j] = tmp;
17.
}
18.
}
19.
}
20.
}
01.
/**
02.
* Bubble sort (descending order)
03.
* @param array array to be sorted
04.
* @auhor Pavel Micka
05.
*/
06.
function
bubbleSort(array){
07.
for
(
var
i = 0; i < array.length - 1; i++) {
08.
for
(
var
j = 0; j < array.length - i - 1; j++) {
09.
if
(array[j] < array[j+1]){
10.
var
tmp = array[j];
11.
array[j] = array[j+1];
12.
array[j+1] = tmp;
13.
}
14.
}
15.
}
16.
}
01.
procedure
BubbleSort(
var
X : ArrayType; N :
integer
);
02.
var
03.
I,
04.
J :
integer
;
05.
begin
06.
for
I :=
2
to
N
do
07.
begin
08.
for
J := N
downto
I
do
09.
if
(X[J] > X[J -
1
])
then
10.
Swap(X[J -
1
], X[J]);
11.
end
12.
end
;
13.
14.
procedure
Swap(
var
X, Y :
integer
);
15.
var
16.
Temp :
integer
;
17.
begin
18.
Temp := X;
19.
X := Y;
20.
Y := Temp
21.
end
;
01.
/**
02.
* Bublinkove razeni (od nejmensiho po nejvetsiho)
03.
* @param $arr pole, ktere bude usporadano
04.
* @author Thomas (www.adamjak.net)
05.
*/
06.
function
bubble_sort(&
$arr
) {
07.
08.
$count
=
count
(
$arr
);
09.
10.
for
(
$i
= 0;
$i
<
$count
- 1;
$i
++) {
11.
for
(
$j
= 0;
$j
<
$count
-
$i
- 1;
$j
++) {
12.
if
(
$arr
[
$j
+ 1] <
$arr
[
$j
]) {
13.
$tmp
=
$arr
[
$j
+ 1];
14.
$arr
[
$j
+ 1] =
$arr
[
$j
];
15.
$arr
[
$j
] =
$tmp
;
16.
}
17.
}
18.
}
19.
}
Rozbor
K seřazení pole bude zapotřebí celkem vnějších cyklů, protože při každém
průchodu seřadíme jeden prvek na konec pole (tímto postupně zmenšujeme úlohu,
proto se každým průchodem zmenšuje i počet procházených prvků ve vnitřním cyklu)
a poslední prvek již není třeba řadit (jeden prvek je triviálně seřazen).
Poslední částí algoritmu je vnitřní podmíka, ve které orientace znaménka rozhoduje, zda-li budeme řadit vzestupně nebo sestupně.
Složitost
Vnitřní cyklus se provede
Což je celkem
sčítanců a podle vzorce na aritmetickou posloupnost je počet operací
Což je asymptoticky (lineární funkce a konstanta rostou asymptoticky pomaleji,
můžeme je zanedbat). Protože jde jak o nejhorší, tak o nejlepší případ, je
výsledná asymptotická složitost
.