1. Binary Search Algorithm (Divide and Conquer)
Binary Search is an efficient way to search for an element in a sorted array, with a time complexity
of O(logn)O(\log n)O(logn).
Kada naudoti: Dvejetainė paieška naudojama, kai turite surūšiuotą masyvą ar kolekciją ir reikia
greitai surasti elementą.
Kaip veikia:
•
•
•
•
•
•
Dvejetainė paieška veikia, nuolat dalindama paieškos sritį per pusę.
Kiekviename žingsnyje lyginate ieškomą elementą su viduriniu masyvo elementu.
Jei vidurinis elementas yra ieškomas elementas, radote atsakymą.
Jei ieškomas elementas yra mažesnis už vidurinį, tęsiate paiešką kairėje masyvo pusėje.
Jei jis didesnis, tęsiate dešinėje pusėje.
Paieška baigiama, kai randamas elementas arba kai paieškos sritis tampa tuščia.
Kodėl naudinga: Paieška vyksta greitai su sudėtingumu O(logn)O(\log n)O(logn), todėl labai
efektyvu surasti elementą surūšiuotuose duomenyse.
public class DvejetainePaieska {
public int paieska(int[] masyvas, int tikslas) {
int kaire = 0, desine = masyvas.length - 1;
while (kaire <= desine) {
int vid = kaire + (desine - kaire) / 2;
if (masyvas[vid] == tikslas) {
return vid;
} else if (masyvas[vid] < tikslas) {
kaire = vid + 1;
} else {
desine = vid - 1;
}
}
return -1; // Nerasta
}
public static void main(String[] args) {
int[] masyvas = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int tikslas = 8;
DvejetainePaieska dvejetainePaieska = new DvejetainePaieska();
int rezultatas = dvejetainePaieska.paieska(masyvas, tikslas);
System.out.println("Tikslas rastas indekse: " + rezultatas);
System.out.println("Indekso reiksme: " + masyvas[rezultatas]);
}
}
2. Two Pointer Technique
Kada naudoti: Naudojamas, kai reikia rasti poras ar sekas masyve ar eilutėje, dažniausiai
surūšiuotame masyve. Masyvo rūšiavimo algoritmai žemiau temose...
Kaip veikia:
• Naudojamos dvi rodyklės, viena pradžioje, kita pabaigoje.
• Lyginate elementus, kuriuos žymi rodyklės, ir pagal poreikį artinate rodykles vieną prie kitos
(priklausomai nuo užduoties).
• Tai leidžia efektyviai spręsti porų radimo ar sekos analizės problemas.
Kodėl naudinga: Šis metodas leidžia spręsti problemas per O(n), o tai yra daug greičiau nei naivus
būdas, kuriame būtų naudojami įdėti ciklai.
public class DviejuRodykliu {
public boolean arYraPorosSuma(int[] masyvas, int tikslas) {
int kaire = 0, desine = masyvas.length - 1;
while (kaire < desine) {
int suma = masyvas[kaire] + masyvas[desine];
if (suma == tikslas) {
return true;
} else if (suma < tikslas) {
kaire++;
} else {
desine--;
}
}
return false;
}
}
V2
import java.util.ArrayList;
import java.util.List;
public class DviejuRodykliu {
public List<int[]> rastiVisasPoras(int[] masyvas, int tikslas) {
List<int[]> poros = new ArrayList<>(); // To store all the pairs
int kaire = 0, desine = masyvas.length - 1;
while (kaire < desine) {
int suma = masyvas[kaire] + masyvas[desine];
if (suma == tikslas) {
poros.add(new int[] {kaire, desine}); // Store the pair
kaire++; // Move both pointers to find next pair
desine--;
} else if (suma < tikslas) {
kaire++;
} else {
desine--;
}
}
return poros;
}
public static void main(String[] args) {
int[] masyvas = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int tikslas = 9;
DviejuRodykliu dviejurodykliu = new DviejuRodykliu();
List<int[]> rezultatai = dviejurodykliu.rastiVisasPoras(masyvas, tikslas);
if (!rezultatai.isEmpty()) {
System.out.println("Poros su nurodyta suma:");
for (int[] pora : rezultatai) {
System.out.println("Indeksai: " + pora[0] + " ir " + pora[1] + " -> Reiksmes: "
+ masyvas[pora[0]] + " ir " + masyvas[pora[1]]
+ ", suma = " + (masyvas[pora[0]] + masyvas[pora[1]]));
}
} else {
System.out.println("Poros su nurodyta suma nera.");
}
}
}
3. Breadth-First Search Plataus Paieškos Algoritmas (BFS) (Grafai ir Medžiai)
Kada naudoti: BFS naudojamas norint pereiti grafą ar medį lygiais, dažnai naudojamas
trumpiausiam keliui rasti nesvoriuose grafuose ar atlikti lygmenų tvarką medyje.
Kaip veikia:
• Naudojama eilė (queue), į kurią įdedame pradžios tašką.
• Tada paimame elementą iš eilės, apdorojame jį ir įdedame jo kaimynus į eilę.
• Taip apeiname visus kaimynus, lygmeniu po lygmens.
Kodėl naudinga: Tai tinka trumpiausio kelio nesvoriuose grafuose paieškai arba lygmens medžio
tvarkai.
import java.util.*;
public class BFS {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
List<Integer> level = new ArrayList<>();
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
level.add(node.val);
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
result.add(level);
}
return result;
}
}
PVZ
Problemos aprašymas:
Jums duotas dvejetainis medis. Turite rasti trumpiausią kelią nuo šaknies iki lapinio mazgo (mazgo,
kuris neturi vaikų). Tai yra minimalus medžio gylis.
1
/\
2 3
/
4
Mažiausias gylis yra 2, nes trumpiausias kelias nuo šaknies iki lapinio mazgo yra šaknis (1) →
mazgas (3).
BFS sprendimas:
Kadangi plataus paieškos algoritmas (BFS) ieško lygiais, jis puikiai tinka rasti mažiausiam gyliui,
nes pirmas aptiktas lapinis mazgas bus atsakymas.
import java.util.*;
class MedzioMazgas {
int reiksme;
MedzioMazgas kaire;
MedzioMazgas desine;
MedzioMazgas(int reiksme) {
this.reiksme = reiksme;
this.kaire = null;
this.desine = null;
}
}
public class MinimumDepthBinaryTree {
public int maziausiasGylis(MedzioMazgas saknis) {
if (saknis == null) return 0;
Queue<MedzioMazgas> eile = new LinkedList<>();
eile.add(saknis);
int gylis = 1; // Pradedame nuo 1 lygmens (šakninio mazgo)
while (!eile.isEmpty()) {
int dydis = eile.size();
for (int i = 0; i < dydis; i++) {
MedzioMazgas mazgas = eile.poll();
// Jei aptinkame lapinį mazgą (neturi vaikų)
if (mazgas.kaire == null && mazgas.desine == null) {
return gylis;
}
// Pridedame kaimynus (vaikus) į eilę
if (mazgas.kaire != null) eile.add(mazgas.kaire);
if (mazgas.desine != null) eile.add(mazgas.desine);
}
gylis++; // Padidiname gylį, kai pereiname prie kito lygmens
}
return gylis;
}
public static void main(String[] args) {
// Sukuriamas medžio mazgų pavyzdys
MedzioMazgas saknis = new MedzioMazgas(1);
saknis.kaire = new MedzioMazgas(2);
saknis.desine = new MedzioMazgas(3);
saknis.kaire.kaire = new MedzioMazgas(4);
// Kviečiame mažiausio gylio metodą
MinimumDepthBinaryTree sprendimas = new MinimumDepthBinaryTree();
int maziausiasGylis = sprendimas.maziausiasGylis(saknis);
// Spausdiname atsakymą
System.out.println("Mažiausias gylis: " + maziausiasGylis);
}
}
Paaiškinimas:
1. Medžio struktūra:
• Šakninis mazgas yra 1.
• Kairysis vaikas yra 2, dešinysis yra 3.
• Mazgas 2 turi kairį vaiką 4.
Medžio struktūra atrodo taip:
1
/\
2 3
/
4
Algoritmo veikimas:
• BFS naudoja eilę. Iš pradžių į eilę įdedame šakninį mazgą.
• Kiekviename ciklo žingsnyje paimame visus mazgus iš dabartinio lygmens.
• Kai pirmą kartą pasiekiame lapinį mazgą (mazgas be vaikų), grąžiname dabartinį
gylį.
• Šiame pavyzdyje mazgas 3 yra pirmasis lapinis mazgas, todėl gylis bus 2.
Kiekvieno žingsnio veiksmai:
1. Įdedame šakninį mazgą (1) į eilę, gylis = 1.
2. Patikriname mazgą 1 ir įdedame jo vaikus 2 ir 3 į eilę.
3. Pereiname prie kito lygmens. Patikriname mazgus 2 ir 3. Kadangi 3 yra lapinis mazgas
(neturi vaikų), grąžiname gylį = 2.
Atsakymas:
Mažiausias gylis: 2
Kodėl BFS tinkamas šiai problemai:
• BFS paieška lygmenimis leidžia rasti pirmą lapinį mazgą kuo greičiau, t.y., randame
mažiausią gylį.
• DFS (gylio paieška) eitų iki galo, bet BFS garantuoja, kad pirmas aptiktas lapinis mazgas
bus arčiausiai šaknies.
Problema: Rasti trumpiausią kelią tarp dviejų miestų
Tarkime, kad turime kelių tinklą tarp miestų, ir norime rasti trumpiausią kelią (pagal minimalią
sustojimų skaičių) tarp dviejų miestų.
Duomenų struktūra:
• Miestai yra mazgai.
• Keliai tarp miestų yra briaunos (kurios nėra svertinės – kiekvienas kelias turi tą pačią
reikšmę).
• Galime naudoti grafą (su kaimynystės sąrašais) miestų ir kelių reprezentacijai.
BFS algoritmo sprendimas:
import java.util.*;
public class TransportoTinklas {
// Grafo struktūra, kur miestai yra raktai, o kaimyniniai miestai yra sąraše
private Map<String, List<String>> keliaiTarpMiestu;
public TransportoTinklas() {
keliaiTarpMiestu = new HashMap<>();
}
// Pridedame kelią tarp dviejų miestų (tai dvipusis kelias)
public void pridetiKelia(String miestas1, String miestas2) {
keliaiTarpMiestu.putIfAbsent(miestas1, new ArrayList<>());
keliaiTarpMiestu.putIfAbsent(miestas2, new ArrayList<>());
keliaiTarpMiestu.get(miestas1).add(miestas2);
keliaiTarpMiestu.get(miestas2).add(miestas1);
}
// Rasti trumpiausią kelią tarp dviejų miestų naudojant BFS
public List<String> rastiTrumpiausiaKelia(String pradinisMiestas, String tikslinisMiestas)
{
// Naudojame eilę miestų perėjimui
Queue<List<String>> eile = new LinkedList<>();
// Pradedame nuo pradinio miesto
eile.add(Arrays.asList(pradinisMiestas));
// Rinkinys aplankytiems miestams
Set<String> aplankyti = new HashSet<>();
aplankyti.add(pradinisMiestas);
while (!eile.isEmpty()) {
List<String> kelias = eile.poll();
String paskutinisMiestas = kelias.get(kelias.size() - 1);
// Jei pasiekėme tikslinį miestą, grąžiname kelią
if (paskutinisMiestas.equals(tikslinisMiestas)) {
return kelias;
}
// Pridedame kaimyninius miestus į eilę, jei jie dar neaplankyti
for (String kaimynas : keliaiTarpMiestu.getOrDefault(paskutinisMiestas, new
ArrayList<>())) {
if (!aplankyti.contains(kaimynas)) {
aplankyti.add(kaimynas);
List<String> naujasKelias = new ArrayList<>(kelias);
naujasKelias.add(kaimynas);
eile.add(naujasKelias);
}
}
}
// Jei kelias nerastas
return new ArrayList<>();
}
public static void main(String[] args) {
TransportoTinklas tinklas = new TransportoTinklas();
// Pridedame kelius tarp miestų
tinklas.pridetiKelia("Vilnius", "Kaunas");
tinklas.pridetiKelia("Kaunas", "Klaipėda");
tinklas.pridetiKelia("Vilnius", "Panevėžys");
tinklas.pridetiKelia("Panevėžys", "Šiauliai");
tinklas.pridetiKelia("Šiauliai", "Klaipėda");
tinklas.pridetiKelia("Klaipėda", "a");
tinklas.pridetiKelia("Vilnius", "c");
tinklas.pridetiKelia("a", "b");
tinklas.pridetiKelia("b", "c");
tinklas.pridetiKelia("c", "d");
tinklas.pridetiKelia("d", "f");
tinklas.pridetiKelia("f", "e");
// Rasti trumpiausią kelią tarp Vilniaus ir Klaipėdos
List<String> trumpiausiasKelias = tinklas.rastiTrumpiausiaKelia("Vilnius", "d");
// Spausdiname rezultatą
if (!trumpiausiasKelias.isEmpty()) {
System.out.println("Trumpiausias kelias: " + String.join(" -> ", trumpiausiasKelias));
} else {
System.out.println("Kelias nerastas.");
}
}
}
Paaiškinimas:
• Grafinė struktūra: Miestai yra raktai, o jų kaimyniniai miestai yra sąrašai. Keliai tarp
miestų įterpiami abiem kryptimis, nes jie dvipusiai (pvz., galite keliauti iš Vilniaus į Kauną
ir atvirkščiai).
• BFS algoritmas: Mes naudojame eilę, kad lygmenimis (vieno žingsnio intervalais)
ieškotume miestų, pradedant nuo pradinio miesto. Kai aptinkame tikslinį miestą, gražiname
trumpiausią kelią iki jo.
• Trumpiausias kelias: BFS garantuoja, kad pirmas rastas kelias bus trumpiausias pagal
mazgų skaičių (sustojimus tarp miestų).
Vilnius <-> Kaunas
Kaunas <-> Klaipėda
Vilnius <-> Panevėžys
Panevėžys <-> Šiauliai
Šiauliai <-> Klaipėda
Panevėžys <-> Kaunas
Trumpiausias kelias: Vilnius -> Kaunas -> Klaipėda
BFS algoritmas pateikia teisingą atsakymą pagal tai, kaip struktūrizuotas kelias ir kaip
algoritmas ieško mazgų.
Kodėl „Vilnius → Kaunas → Klaipėda“ atsirado pirmiau, nei „Vilnius →
Šiauliai → Klaipėda“?
1. BFS algoritmas veikia lygmenimis:
• Pirma jis patikrina visus kaimyninius miestus, esančius tiesiogiai šalia pradinio
miesto (t. y., tuos miestus, su kuriais jungiasi kelias tiesiogiai iš Vilniaus). Vilnius
turi tiesioginius kelius su Kaunu ir Panevėžiu.
• Kito žingsnio metu jis tikrina miestus, su kuriais jungiasi Kaunas ir Panevėžys.
2. Kaunas randamas anksčiau nei Šiauliai:
• Kadangi iš Vilniaus į Kauną yra tiesioginis kelias, Kaunas pirmas įtraukiamas į eilę.
BFS prioritizuoja Kauno kaimynus, nes eina lygmenimis.
• Tik po to, kai yra patikrinami Kauno ir Panevėžio kaimynai, algoritmas pasiekia
Šiaulius.
3. Trumpesnis kelias per Kauną:
• Iš Vilniaus į Kauną yra vienas žingsnis, ir iš Kauno į Klaipėdą yra dar vienas
žingsnis. Taigi šis kelias yra 2 žingsnių kelias.
• Kelias per Šiaulius turi bent 3 žingsnius: „Vilnius → Panevėžys → Šiauliai →
Klaipėda“. BFS algoritmas randa trumpesnį kelią per Kauną, nes šis kelias turi
mažiau mazgų.
Grafas:
Vilnius → Kaunas → Klaipėda
Vilnius → Panevėžys → Šiauliai → Klaipėda
Vilnius → Kaunas → Klaipėda yra trumpesnis kelias, nes jis turi tik 2 mazgus (sustojimus).
• Vilnius → Panevėžys → Šiauliai → Klaipėda turi 3 mazgus, todėl jis yra ilgesnis.
Kodėl BFS neras kelio per Šiaulius pirmiau?
BFS algoritmas visuomet pirmiausia baigia tikrinti tiesioginius kaimynus prieš pereidamas prie jų
kaimynų. Šiuo atveju:
• BFS tikrina Kauno kaimynus anksčiau nei Panevėžio, nes Kaunas yra pirmasis kaimynas.
• Kai BFS aptinka Klaipėdą per Kauną (per 2 žingsnius), jis grąžina šį trumpesnį kelią.
Apibendrinant:
Algoritmas randa trumpiausią kelią pagal mazgų skaičių, o ne atstumą, nebent keliai turėtų svorius
(pvz., kilometrus). Kadangi kelias per Kauną yra 2 žingsnių, o per Šiaulius – 3 žingsnių, BFS
pasirenka trumpesnį variantą.
Rūšiavimo algoritmai:
1. Bubble rūšiavimas (Bubble Sort)
Burės rūšiavimas yra paprastas rūšiavimo algoritmas, kuris lygina gretimus elementus ir keičia jų
vietas, jei jie nėra teisingoje tvarkoje. Šis procesas kartojamas tol, kol masyvas bus surūšiuotas.
Java
/*
5 elementai
0,1,2,3,4
pirmas ciklas iki priespaskutinio ementai tai 4, gaunasi kad paskutinio
skaiciaus neimam.
5-0-1=4
5-1-1=3
5-2-1=2
5-3-1=1
5-4-1=0
// pirmas ciklas nurodo kiek kartu procesas turi buti pakartotas ty. Iki pries
paskutinio
//vidinis ciklas peržiūri masyvą ir atlieka reikalingus veiksmus, -1 kad
neperžengtu ribu, jei 5 elementai ilgis – 0 -1, reik prisimint kad cia indeksai.
Ir be -1, paskutini karta butu atliekamas lyginimas su neegzistuojanciu elementu
masyvo
*/
Copy code
public class BurėsRūšiavimas {
public static void burėsRūšiavimas(int[] masyvas) {
int n = masyvas.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (masyvas[j] > masyvas[j + 1]) {
// Keičia vietomis masyvo elementus
int temp = masyvas[j];
masyvas[j] = masyvas[j + 1];
masyvas[j + 1] = temp;
}
}
}
}
}
public static void main(String[] args) {
int[] masyvas = {64, 34, 25, 12, 22, 11, 90};
burėsRūšiavimas(masyvas);
System.out.println("Surūšiuotas masyvas:");
for (int i : masyvas) {
System.out.print(i + " ");
}
}
2. Greitasis rūšiavimas (Quick Sort)
Greitasis rūšiavimas yra efektyvus rūšiavimo algoritmas, kuris remiasi dalinimo ir valdymo
principu.
java
Copy code
public class GreitasisRūšiavimas {
public static void greitasRūšiavimas(int[] masyvas, int pradzia, int
pabaiga) {
if (pradzia < pabaiga) {
int pivot = padalinti(masyvas, pradzia, pabaiga);
greitasRūšiavimas(masyvas, pradzia, pivot - 1);
greitasRūšiavimas(masyvas, pivot + 1, pabaiga);
}
}
private static int padalinti(int[] masyvas, int pradzia, int pabaiga) {
int pivot = masyvas[pabaiga];
int i = pradzia - 1;
for (int j = pradzia; j < pabaiga; j++) {
if (masyvas[j] <= pivot) {
i++;
int temp = masyvas[i];
masyvas[i] = masyvas[j];
masyvas[j] = temp;
}
}
int temp = masyvas[i + 1];
masyvas[i + 1] = masyvas[pabaiga];
masyvas[pabaiga] = temp;
return i + 1;
}
public static void main(String[] args) {
int[] masyvas = {10, 7, 8, 9, 1, 5};
greitasRūšiavimas(masyvas, 0, masyvas.length - 1);
System.out.println("Surūšiuotas masyvas:");
for (int i : masyvas) {
System.out.print(i + " ");
}
}
}
3. Sujungimo rūšiavimas (Merge Sort)
Sujungimo rūšiavimas yra efektyvus algoritmas, kuris rūšiuoja duomenis dalijant masyvą į
mažesnes dalis, rūšiuojant jas ir galiausiai sujungiant.
java
Copy code
public class SujungimoRūšiavimas {
public static void sujungimoRūšiavimas(int[] masyvas, int pradzia, int
pabaiga) {
if (pradzia < pabaiga) {
int vidurys = (pradzia + pabaiga) / 2;
sujungimoRūšiavimas(masyvas, pradzia, vidurys);
sujungimoRūšiavimas(masyvas, vidurys + 1, pabaiga);
sujungti(masyvas, pradzia, vidurys, pabaiga);
}
}
private static void sujungti(int[] masyvas, int pradzia, int vidurys, int
pabaiga) {
int n1 = vidurys - pradzia + 1;
int n2 = pabaiga - vidurys;
int[] kairysis = new int[n1];
int[] dešinysis = new int[n2];
System.arraycopy(masyvas, pradzia, kairysis, 0, n1);
System.arraycopy(masyvas, vidurys + 1, dešinysis, 0, n2);
int i = 0, j = 0;
int k = pradzia;
while (i < n1 && j < n2) {
if (kairysis[i] <= dešinysis[j]) {
masyvas[k++] = kairysis[i++];
} else {
masyvas[k++] = dešinysis[j++];
}
}
while (i < n1) {
masyvas[k++] = kairysis[i++];
}
while (j < n2) {
masyvas[k++] = dešinysis[j++];
}
}
public static void main(String[] args) {
int[] masyvas = {38, 27, 43, 3, 9, 82, 10};
sujungimoRūšiavimas(masyvas, 0, masyvas.length - 1);
System.out.println("Surūšiuotas masyvas:");
for (int i : masyvas) {
System.out.print(i + " ");
}
}
}
4. Įterpimo rūšiavimas (Insertion Sort)
Įterpimo rūšiavimas veikia taip, kaip žmonės rūšiuoja kortas – elementas yra įterpiamas į teisingą
vietą, palyginus su jau surūšiuotais elementais.
java
Copy code
public class ĮterpimoRūšiavimas {
public static void įterpimoRūšiavimas(int[] masyvas) {
for (int i = 1; i < masyvas.length; i++) {
int key = masyvas[i];
int j = i - 1;
while (j >= 0 && masyvas[j] > key) {
masyvas[j + 1] = masyvas[j];
j--;
}
masyvas[j + 1] = key;
}
}
}
public static void main(String[] args) {
int[] masyvas = {12, 11, 13, 5, 6};
įterpimoRūšiavimas(masyvas);
System.out.println("Surūšiuotas masyvas:");
for (int i : masyvas) {
System.out.print(i + " ");
}
}
Šie pavyzdžiai parodo, kaip skirtingi rūšiavimo algoritmai gali būti įgyvendinami Java kalba.
Pasirinkite tinkamą algoritmą priklausomai nuo jūsų poreikių ir masyvo dydžio.
Rūšiavimas su biblioteka
https://www.geeksforgeeks.org/arrays-sort-in-java-with-examples/
import java.util.Arrays;
public class Main
{
public static void main(String args[])
{
int[] arr = { 5, -2, 23, 7, 87, -42, 509 };
System.out.println("The original array is: ");
for (int num : arr) {
System.out.print(num + " ");
}
Arrays.sort(arr);
System.out.println("\nThe sorted array is: ");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )