Tri najbolja rezultata
Učitava se broj n (3 ≤ n ≤ 1000) i zatim n rezultata takmičara. Ispiši tri najbolja (najveća) rezultata, od najvećeg ka manjem.
Primer
Ulaz
6
45 78 12 99 78 60Izlaz
99 78 78Sortirati niz znači poređati njegove elemente po veličini – od najmanjeg ka najvećem (rastuće) ili od najvećeg ka najmanjem (opadajuće). U ovoj lekciji upoznajemo tri jednostavna algoritma: sortiranje izborom, umetanjem i metodom mehurića.
Sortiran niz je mnogo lakše pretraživati i obrađivati: najmanji i najveći element su na krajevima, jednaki elementi su jedan do drugog, a traženi broj može da se nađe binarnom pretragom u nekoliko koraka umesto prolaskom kroz ceo niz.
Ako u nizu ima jednakih elemenata, umesto „rastuće“ tačnije je reći neopadajuće (svaki sledeći je veći ili jednak prethodnom). Na primer, niz 2 5 5 8 je sortiran neopadajuće.
Ideja: pronađi najmanji element i zameni ga sa prvim. Zatim u ostatku niza (od drugog elementa) pronađi najmanji i zameni ga sa drugim, i tako dalje. Posle koraka i prvih i + 1 elemenata je na svom konačnom mestu.
| Korak | Niz posle koraka | Šta se desilo |
|---|---|---|
| početak | 5 2 9 1 7 | |
| i = 0 | 1 2 9 5 7 | najmanji je 1, menja mesto sa 5 |
| i = 1 | 1 2 9 5 7 | najmanji u ostatku je 2, već je na mestu |
| i = 2 | 1 2 5 9 7 | najmanji u ostatku je 5, menja mesto sa 9 |
| i = 3 | 1 2 5 7 9 | najmanji u ostatku je 7, menja mesto sa 9 |
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int a[1000];
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n - 1; i++) {
int minPoz = i; // pozicija najmanjeg u delu a[i..n-1]
for (int j = i + 1; j < n; j++)
if (a[j] < a[minPoz]) minPoz = j;
swap(a[i], a[minPoz]); // najmanji ide na mesto i
}
for (int i = 0; i < n; i++) cout << a[i] << " ";
cout << endl;
return 0;
}
Za opadajući poredak dovoljno je tražiti najveći umesto najmanjeg: if (a[j] > a[maxPoz]).
if (a[j] < a[i]) swap(a[i], a[j]);). I ona sortira tačno, ali pravi mnogo više zamena. Verzija sa pamćenjem pozicije najmanjeg pravi najviše n − 1 zamena.Ideja: kao kada slažeš karte u ruci. Levi deo niza je već sortiran. Uzimaš sledeći element, pomeraš udesno sve veće elemente iz sortiranog dela i ubacuješ ga na oslobođeno mesto.
| Korak | Niz posle koraka | Umetnuti element |
|---|---|---|
| početak | 5 | 2 9 1 7 | sortiran deo je samo 5 |
| i = 1 | 2 5 | 9 1 7 | 2 ide ispred 5 |
| i = 2 | 2 5 9 | 1 7 | 9 ostaje na mestu |
| i = 3 | 1 2 5 9 | 7 | 1 ide na početak (9, 5, 2 se pomeraju) |
| i = 4 | 1 2 5 7 9 | 7 ide između 5 i 9 |
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int a[1000];
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 1; i < n; i++) {
int x = a[i]; // element koji umećemo
int j = i - 1;
while (j >= 0 && a[j] > x) { // pomeramo veće elemente za jedno mesto udesno
a[j + 1] = a[j];
j--;
}
a[j + 1] = x; // x ide na oslobođeno mesto
}
for (int i = 0; i < n; i++) cout << a[i] << " ";
cout << endl;
return 0;
}
Sortiranje umetanjem je vrlo brzo kada je niz skoro sortiran: tada se elementi skoro ne pomeraju.
Ideja: prolazimo kroz niz i poredimo susedne elemente; ako su u pogrešnom redosledu, menjamo im mesta. Posle prvog prolaza najveći element „ispliva“ na kraj niza, kao mehurić. Ako u nekom prolazu nije bilo nijedne zamene, niz je sortiran i možemo da stanemo.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int a[1000];
for (int i = 0; i < n; i++) cin >> a[i];
for (int prolaz = 0; prolaz < n - 1; prolaz++) {
bool bilo = false; // da li je bilo zamena u ovom prolazu
for (int j = 0; j < n - 1 - prolaz; j++) { // poslednjih "prolaz" elemenata je već na mestu
if (a[j] > a[j + 1]) {
swap(a[j], a[j + 1]);
bilo = true;
}
}
if (!bilo) break; // niz je već sortiran
}
for (int i = 0; i < n; i++) cout << a[i] << " ";
cout << endl;
return 0;
}
Sva tri algoritma imaju dve ugnježdene petlje, pa za niz od n elemenata rade oko n²/2 poređenja. Kažemo da im je složenost O(n²) (čita se „o od n na kvadrat“).
| Algoritam | Broj poređenja | Broj zamena | Skoro sortiran niz | Stabilan |
|---|---|---|---|---|
| Izbor | uvek oko n²/2 | najviše n − 1 | ne pomaže | ne |
| Umetanje | od n do n²/2 | do n²/2 pomeranja | vrlo brzo | da |
| Mehurić | od n do n²/2 | do n²/2 | brzo (prekid ako nema zamena) | da |
Stabilan algoritam ne menja međusobni redosled jednakih elemenata – to je važno kada sortiramo, na primer, učenike po bodovima, a želimo da učenici sa istim brojem bodova ostanu po redosledu prijave.
| n | n² (približno operacija) | Vreme |
|---|---|---|
| 1 000 | 1 000 000 | trenutno |
| 10 000 | 100 000 000 | oko sekunde |
| 1 000 000 | 1012 | satima – predugo |
Za veće nizove koriste se efikasni algoritmi složenosti O(n log n): sortiranje objedinjavanjem i brzo sortiranje. Na takmičenjima se u praksi koristi gotova funkcija sort.
Za svaki zadatak postoji primer, uputstvo i rešenje. Rešenja su provereno tačna na primerima iz teksta.
Učitava se broj n (3 ≤ n ≤ 1000) i zatim n rezultata takmičara. Ispiši tri najbolja (najveća) rezultata, od najvećeg ka manjem.
6
45 78 12 99 78 6099 78 78Dato je n brojeva, n je neparno (1 ≤ n ≤ 999). Medijana je broj koji se nalazi u sredini kada se brojevi poređaju po veličini. Ispiši medijanu.
5
7 1 9 3 553
10 10 210Za dati niz od n brojeva (1 ≤ n ≤ 1000) ispiši koliko zamena susednih elemenata napravi metoda mehurića dok ne sortira niz rastuće.
5
5 2 9 1 754
1 2 3 40i + 1, a ne od 0.a[j] i a[j + 1], pa j ide najviše do n − 2 – inače se čita element van niza.j >= 0 mora biti pre a[j] > x, da se ne bi čitalo a[-1].sort iz biblioteke <algorithm> – algoritmi O(n²) su prespori.1. Koliko najviše zamena napravi sortiranje izborom (verzija sa pamćenjem pozicije najmanjeg) za niz od n elemenata?
2. Koji algoritam je najbrži za niz koji je već skoro sortiran?
3. Koliko poređenja otprilike radi algoritam složenosti O(n²) za n = 10 000?
4. Šta znači da je sortiranje stabilno?
| Sortiranje niza u neopadajućem ili nerastućem poretku podrazumeva nalaženje jedne permutacije elemenata niza u kojoj se elementi pojavljuju u neopadajućem tj. nerastućem poretku. |
|
To radi sledeći kod:
Postupak se ponavlja i za sledeći podniz gde se pronalazi največi za sve ostle članove sa desne strane izuzev prva dva. Ponavljanjem postupka imamo sve manje i manje podnizove koje sortiramo dok ne sortiramo do kraja.
Konačno ceo kod za sortiranje:| Algoritam sortiranja koji se pokazao najbržim. Sastoji se u rekurzivnom ponavljanju razdvajanja elemenata niza oko neke vrednosti koja je usvojena za "srednju". Pročitajte više o tome na stranici: Brzo Sortiranje |
![]() |
| Prethodno |<Osnovne strukture podataka |
Sledeće Binarna pretraga>| |