gitweb on Svarog

projekti pod git sistemom za održavanje verzija -- projects under the git version control system
Stabla, primer konkretnog stabla osoba
authorIvan Pribela <ivanpribela@gmail.com>
Sat, 26 Dec 2015 16:15:55 +0000 (17:15 +0100)
committerDoni Pracner <quinnuendo@gmail.com>
Sat, 26 Dec 2015 16:15:55 +0000 (17:15 +0100)
Stabla/konkretnoStablo/MinimalnoStablo.java [new file with mode: 0644]
Stabla/konkretnoStablo/MojeStablo.java [new file with mode: 0644]
Stabla/konkretnoStablo/Osoba.java [new file with mode: 0644]
Stabla/konkretnoStablo/Osobe.txt [new file with mode: 0644]
Stabla/konkretnoStablo/README.txt [new file with mode: 0644]
Stabla/konkretnoStablo/StabloOsobaProgram.java [new file with mode: 0644]
Stabla/konkretnoStablo/TreeIO.java [new file with mode: 0644]
Stabla/konkretnoStablo/Zadatak.txt [new file with mode: 0644]

diff --git a/Stabla/konkretnoStablo/MinimalnoStablo.java b/Stabla/konkretnoStablo/MinimalnoStablo.java
new file mode 100644 (file)
index 0000000..11da646
--- /dev/null
@@ -0,0 +1,27 @@
+// Konkretno stablo koje sadrzi Osobe\r
+class StabloO {\r
+    private static class Cvor {\r
+       Osoba osoba;\r
+       Cvor levo;\r
+       Cvor desno;\r
+    }\r
+    \r
+    private Cvor koren;\r
+}\r
+\r
+// Glavna klasa\r
+public class MinimalnoStablo {\r
+\r
+       // Glavni program\r
+       public static void main(String[] args) {\r
+\r
+               // Napravimo pomocni objekat za ucitavanje i ispisivanje\r
+               TreeIO<StabloO> io = new TreeIO<>(StabloO.class);\r
+\r
+               // Procitamo stablo iz fajla\r
+               StabloO stablo = io.read(Svetovid.in("Osobe.txt"));\r
+\r
+               // Ispisemo ucitano stablo\r
+               io.print(Svetovid.out, stablo);\r
+       }\r
+}\r
diff --git a/Stabla/konkretnoStablo/MojeStablo.java b/Stabla/konkretnoStablo/MojeStablo.java
new file mode 100644 (file)
index 0000000..a18c445
--- /dev/null
@@ -0,0 +1,33 @@
+// Konkretno stablo koje sadrzi Osobe\r
+// Moze imati proizvoljno ime, ali ga treba promeniti u glavnom programu\r
+// na adekatnim mestima\r
+class BiloSta {\r
+    // treba definisati staticku podklasu koja predstavlja cvor\r
+    \r
+    // cvor treba da ima pokazivace na levo i desno podstablo\r
+    // da bi se razlikovalo koji je koji, TreeIO ocekuje da\r
+    // levo pocinje sa slovom "l", dok desno pocinje sa slovom\r
+    // "d" ili "r".\r
+    \r
+    // klasa stablo treba da ima pokazivac na koren definisanog tipa cvor\r
+\r
+    //ako klasa nije definisana kako TreeIO ocekuje, bunice se na pokretanju\r
+    \r
+}\r
+\r
+// Glavna klasa\r
+public class MojeStablo {\r
+\r
+       // Glavni program\r
+       public static void main(String[] args) {\r
+\r
+               // Napravimo pomocni objekat za ucitavanje i ispisivanje\r
+               TreeIO<BiloSta> io = new TreeIO<>(BiloSta.class);\r
+\r
+               // Procitamo stablo iz fajla\r
+               BiloSta stablo = io.read(Svetovid.in("Osobe.txt"));\r
+\r
+               // Ispisemo ucitano stablo\r
+               io.print(Svetovid.out, stablo);\r
+       }\r
+}\r
diff --git a/Stabla/konkretnoStablo/Osoba.java b/Stabla/konkretnoStablo/Osoba.java
new file mode 100644 (file)
index 0000000..6d0fee5
--- /dev/null
@@ -0,0 +1,77 @@
+\r
+import java.util.Objects;\r
+\r
+// Tip podataka koji predstavlja jednu osobu\r
+public class Osoba {\r
+\r
+       private final String ime;\r
+       private final String prezime;\r
+       private final int plata;\r
+\r
+       public Osoba(String ime, String prezime, int plata) {\r
+               if (ime == null) {\r
+                       throw new IllegalArgumentException("ime");\r
+               }\r
+               this.ime = ime;\r
+               if (prezime == null) {\r
+                       throw new IllegalArgumentException("prezime");\r
+               }\r
+               this.prezime = prezime;\r
+               this.plata = plata;\r
+       }\r
+\r
+       public String getIme() {\r
+               return ime;\r
+       }\r
+\r
+       public String getPrezime() {\r
+               return prezime;\r
+       }\r
+\r
+       public int getPlata() {\r
+               return plata;\r
+       }\r
+\r
+       @Override\r
+       public int hashCode() {\r
+               final int prostBroj = 31;\r
+               int rezultat = 1;\r
+               rezultat = prostBroj * rezultat + ime.hashCode();\r
+               rezultat = prostBroj * rezultat + prezime.hashCode();\r
+               return rezultat;\r
+       }\r
+\r
+       @Override\r
+       public boolean equals(Object obj) {\r
+               if (this == obj) {\r
+                       return true;\r
+               }\r
+               if (obj == null) {\r
+                       return false;\r
+               }\r
+               if (getClass() != obj.getClass()) {\r
+                       return false;\r
+               }\r
+               Osoba that = (Osoba) obj;\r
+               if (!Objects.equals(this.ime, that.ime)) {\r
+                       return false;\r
+               }\r
+               if (!Objects.equals(this.prezime, that.prezime)) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+\r
+       @Override\r
+       public String toString() {\r
+               return ime + " " + prezime + " " + plata;\r
+       }\r
+\r
+       public static Osoba parseOsoba(String string) {\r
+               if (string == null) {\r
+                       return null;\r
+               }\r
+               String[] delovi = string.split(" ");\r
+               return new Osoba(delovi[0], delovi[1], Integer.parseInt(delovi[2]));\r
+       }\r
+}\r
diff --git a/Stabla/konkretnoStablo/Osobe.txt b/Stabla/konkretnoStablo/Osobe.txt
new file mode 100644 (file)
index 0000000..3ca4dc8
--- /dev/null
@@ -0,0 +1,99 @@
+                /-----(o) Pera Peric 21953\r
+                |\r
+         /-----(o) Paja Pajic 31962\r
+         |      |\r
+         |      |             /-----(o) Mitar Mitrovic 21958\r
+         |      |             |      |\r
+         |      |             |      \-----(o) Dara Darinkov 31968\r
+         |      |             |\r
+         |      |      /-----(o) Mile Milic 21962\r
+         |      |      |      |\r
+         |      |      |      |      /-----(o) Stefan Stefan-Stefan 21948\r
+         |      |      |      |      |\r
+         |      |      |      \-----(o) Nemanja Nemanjic 41979\r
+         |      |      |\r
+         |      \-----(o) Svetozar Svetozarevic 21954\r
+         |             |\r
+         |             \-----(o) Zlaja Zlajic 31981\r
+         |\r
+  /-----(o) Vuk Wolfeschlegelsteinhausenberger 41966\r
+  |      |\r
+  |      |      /-----(o) Nina Ninkov 21971\r
+  |      |      |\r
+  |      \-----(o) Raja Rajkovic 31985\r
+  |             |\r
+  |             |      /-----(o) Djoka Djokic 31979\r
+  |             |      |\r
+  |             \-----(o) Srbislava Srbislavac 41969\r
+  |                    |\r
+  |                    \-----(o) Nikolina Nikolic 31944\r
+  |                           |\r
+  |                           \-----(o) Zvonko Zvonkov 31983\r
+  |\r
+-(o) Petar Petrovic 51945\r
+  |\r
+  |      /-----(o) Marko Markovic 31923\r
+  |      |      |\r
+  |      |      |      /-----(o) Jakov Karajakov 21966\r
+  |      |      |      |      |\r
+  |      |      |      |      |      /-----(o) Janko Jankovic 21959\r
+  |      |      |      |      |      |\r
+  |      |      |      |      \-----(o) Tuta Tutevski 21974\r
+  |      |      |      |             |\r
+  |      |      |      |             \-----(o) Zorana Zoranovic-Zoranski 21955\r
+  |      |      |      |\r
+  |      |      \-----(o) Zdravko Dren 61823\r
+  |      |             |\r
+  |      |             \-----(o) Filip Filipovic 21957\r
+  |      |\r
+  \-----(o) Maja Majic 41972\r
+         |\r
+         |                    /-----(o) Mislav Mislavski 21960\r
+         |                    |\r
+         |             /-----(o) Ljubisava Ljubisavljevic 21959\r
+         |             |      |\r
+         |             |      |             /-----(o) Pera Peric 21973\r
+         |             |      |             |\r
+         |             |      |      /-----(o) Joksim Joksimovic 21959\r
+         |             |      |      |      |\r
+         |             |      |      |      \-----(o) Mika Mikic 31970\r
+         |             |      |      |             |\r
+         |             |      |      |             \-----(o) Baja Bajic 21967\r
+         |             |      |      |\r
+         |             |      \-----(o) Zrinko Zrinkovic 31965\r
+         |             |             |\r
+         |             |             \-----(o) Hadzija Hadzi-Hadzic 21963\r
+         |             |                    |\r
+         |             |                    \-----(o) Jova Jovic 11943\r
+         |             |                           |\r
+         |             |                           \-----(o) Tatjana Tatjanic 11972\r
+         |             |                                  |\r
+         |             |                                  \-----(o) Leposava Leposavljevic 21981\r
+         |             |                                         |\r
+         |             |                                         |      /-----(o) Zora Zoric 11969\r
+         |             |                                         |      |\r
+         |             |                                         \-----(o) Milos Milosevic 11953\r
+         |             |                                                |\r
+         |             |                                                \-----(o) Jovan Jovanovic 11975\r
+         |             |\r
+         |      /-----(o) Ivana Ivanovic 31977\r
+         |      |\r
+         \-----(o) Marinko Marinkovic 41965\r
+                |\r
+                \-----(o) Marina Marinovic 31984\r
+                       |\r
+                       \-----(o) Gojko Gajkovic 31967\r
+                              |\r
+                              |             /-----(o) Milan McMilan 21966\r
+                              |             |      |\r
+                              |             |      |             /-----(o) Milena Mileski 21977\r
+                              |             |      |             |\r
+                              |             |      |      /-----(o) Miladinka Miladinovic 21964\r
+                              |             |      |      |\r
+                              |             |      \-----(o) Nikola Nikolic-Nikolic 21981\r
+                              |             |             |\r
+                              |             |             \-----(o) Danijela Danijelac 21979\r
+                              |             |\r
+                              |      /-----(o) Strahinja Strahimirovic 21976\r
+                              |      |\r
+                              \-----(o) Lazar Lazarevic 21976\r
diff --git a/Stabla/konkretnoStablo/README.txt b/Stabla/konkretnoStablo/README.txt
new file mode 100644 (file)
index 0000000..77632fa
--- /dev/null
@@ -0,0 +1,23 @@
+Primeri binarnih stabala sa konkretnim podacima klase Osoba.
+
+- Osoba.java - klasa koja predstavlja osobu: dati su ime,
+prezime i plata. Instance ove klase se cuvaju u binarnim
+stablima.
+
+- StabloOsobaProgram.java - program koji demonstrira neke
+operacije nad konkretnim stablo osoba
+
+- MinimalnoStablo.java - osnova koja definise samo potrebne
+klase i u koju se mogu dodavati novi metodi po potrebi
+
+- MojeStablo.java - primer koji pokazuje kako se mogu 
+samostalno definisati klase koje predstavljaju stablo.
+
+- TreeIO.java - pomocna klasa za rad sa stablima, nije
+neophodno znati kako ona radi. Kod za ucitavanje stabla
+iz fajla kakav je dat je dat u glavnim programima, kao i
+kod za stampanje celog stabla na ekran.
+
+- Osobe.txt - fajl koji predstavlja stablo osoba.
+
+- Zadatak.txt - dodatni zadaci za samostalnu vezbu.
\ No newline at end of file
diff --git a/Stabla/konkretnoStablo/StabloOsobaProgram.java b/Stabla/konkretnoStablo/StabloOsobaProgram.java
new file mode 100644 (file)
index 0000000..327d75a
--- /dev/null
@@ -0,0 +1,271 @@
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.NoSuchElementException;\r
+import java.util.Objects;\r
+\r
+import org.svetovid.Svetovid;\r
+\r
+// Konkretno stablo koje sadrzi ocene\r
+class StabloOsoba {\r
+\r
+       // Tip koji opisuje jedan cvor u stablu\r
+       protected static class Cvor {\r
+\r
+               // Sadrzaj cvora\r
+               public final Osoba osoba;\r
+\r
+               // Levo i desno podstablo\r
+               public final Cvor levo;\r
+               public final Cvor desno;\r
+\r
+               // Jedini konstruktor\r
+               public Cvor(Osoba osoba, Cvor levo, Cvor desno) {\r
+                       this.osoba = osoba;\r
+                       this.levo = levo;\r
+                       this.desno = desno;\r
+               }\r
+       }\r
+\r
+       // Stablo ima referencu na korenski cvor\r
+       protected final Cvor koren;\r
+\r
+       // Kreiramo prazno stablo\r
+       public StabloOsoba() {\r
+               koren = null;\r
+       }\r
+\r
+       // Kreiramo stablo sa jednom osobom u korenu\r
+       // i praznim evim i desnim podstablom\r
+       public StabloOsoba(Osoba osoba) {\r
+               koren = new Cvor(osoba, null, null);\r
+       }\r
+\r
+       // Specijalan konstruktor koji koriste neki metodi ove klase\r
+       protected StabloOsoba(Cvor koren) {\r
+               this.koren = koren;\r
+       }\r
+\r
+       // Vraca osobu koja je direktor cele firme\r
+       public Osoba getDirektor() {\r
+               if (koren == null) { // Stablo je prazno\r
+                       throw new NoSuchElementException();\r
+               }\r
+               return koren.osoba;\r
+       }\r
+\r
+       // Vraca ukupan broj osoba u stablu\r
+       public int brojOsoba() {\r
+       return brojOsoba(koren);\r
+       }\r
+\r
+    protected static int brojOsoba(Cvor cvor) {\r
+       if (cvor == null) {\r
+               return 0;\r
+       }\r
+               int broj = 1;\r
+               broj = broj + brojOsoba(cvor.levo);\r
+               broj = broj + brojOsoba(cvor.desno);\r
+               return broj;\r
+    }\r
+\r
+    // Stampa sve osobe\r
+    public void stampajSveOsobe() {\r
+       stampajSveOsobe(koren);\r
+    }\r
+\r
+    protected static void stampajSveOsobe(Cvor cvor) {\r
+       if (cvor == null) {\r
+               return;\r
+       }\r
+       stampajSveOsobe(cvor.levo);\r
+       Svetovid.out.println(cvor.osoba);\r
+       stampajSveOsobe(cvor.desno);\r
+    }\r
+\r
+    // Vraca listu svih osoba\r
+    public List<Osoba> sveOsobe() {\r
+       List<Osoba> osobe = new ArrayList<>();\r
+       sveOsobe(koren, osobe);\r
+       return osobe;\r
+    }\r
+\r
+    protected static void sveOsobe(Cvor cvor, List<Osoba> lista) {\r
+       if (cvor == null) {\r
+               return;\r
+       }\r
+       sveOsobe(cvor.levo, lista);\r
+       lista.add(cvor.osoba);\r
+       sveOsobe(cvor.desno, lista);\r
+    }\r
+\r
+    // Pronalazi datu osobu i vraca stablo sa korenom u njoj\r
+    public StabloOsoba pronadji(Osoba osoba) {\r
+       Cvor cvor = pronadji(koren, osoba);\r
+       if (cvor == null) {\r
+               return null;\r
+       }\r
+       return new StabloOsoba(cvor);\r
+    }\r
+\r
+    protected static Cvor pronadji(Cvor cvor, Osoba osoba) {\r
+       if (cvor == null) {\r
+               return null;\r
+       }\r
+       if (Objects.equals(cvor.osoba, osoba)) {\r
+               return cvor;\r
+       }\r
+       Cvor nadjenLevo = pronadji(cvor.levo, osoba);\r
+       if (nadjenLevo != null) {\r
+               return nadjenLevo;\r
+       }\r
+       Cvor nadjenDesno = pronadji(cvor.desno, osoba);\r
+       if (nadjenDesno != null) {\r
+               return nadjenDesno;\r
+       }\r
+       return null;\r
+    }\r
+\r
+    // Pronalazi sefa date osobe\r
+    public Osoba sefOd(Osoba podredjeni) {\r
+       Cvor cvor = sefOd(koren, null, podredjeni);\r
+       if (cvor == null) {\r
+               return null;\r
+       }\r
+       return cvor.osoba;\r
+    }\r
+    \r
+    protected static Cvor sefOd(Cvor tekuci, Cvor roditelj, Osoba podredjeni) {\r
+       if (tekuci == null) {\r
+               return null;\r
+       }\r
+       if (Objects.equals(tekuci.osoba, podredjeni)) {\r
+               return roditelj;\r
+       }\r
+       Cvor roditeljLevo = sefOd(tekuci.levo, tekuci, podredjeni);\r
+       if (roditeljLevo != null) {\r
+               return roditeljLevo;\r
+       }\r
+       Cvor roditeljDesno = sefOd(tekuci.desno, tekuci, podredjeni);\r
+       if (roditeljDesno != null) {\r
+               return roditeljDesno;\r
+       }\r
+       return null;\r
+    }\r
+\r
+    // Vraca listu svih osoba sa platom manjom od granice\r
+    public List<Osoba> sviSaPlatomIspod(int granica) {\r
+       List<Osoba> osobe = new ArrayList<>();\r
+       sviSaPlatomIspod(koren, osobe, granica);\r
+       return osobe;\r
+    }\r
+\r
+    protected static void sviSaPlatomIspod(Cvor cvor, List<Osoba> lista, int granica) {\r
+       if (cvor == null) {\r
+               return;\r
+       }\r
+       if (cvor.osoba.getPlata() < granica) {\r
+               lista.add(cvor.osoba);\r
+       }\r
+       sviSaPlatomIspod(cvor.levo, lista, granica);\r
+       sviSaPlatomIspod(cvor.desno, lista, granica);\r
+    }\r
+\r
+    // Vraca listu svih osoba podredjenih datoj\r
+    public List<Osoba> sviPodredjeni(Osoba sef) {\r
+       List<Osoba> osobe = new ArrayList<>();\r
+       Cvor cvor = pronadji(koren, sef);\r
+       if (cvor != null) {\r
+               sveOsobe(cvor, osobe);\r
+       }\r
+       return osobe;\r
+    }\r
+\r
+    // Ispisuje sve puteve u stablu od korena do svih listova\r
+    public void odDirektoraDoSpremacice() {\r
+       List<Osoba> put = new ArrayList<>();\r
+       odDirektoraDoSpremacice(koren, put);\r
+    }\r
+\r
+    protected static void odDirektoraDoSpremacice(Cvor cvor, List<Osoba> put) {\r
+       if (cvor == null) {\r
+               return;\r
+       }\r
+       put.add(cvor.osoba);\r
+       if ((cvor.levo == null) && (cvor.desno == null)) {\r
+               Svetovid.out.println(put);\r
+       }\r
+       odDirektoraDoSpremacice(cvor.levo, put);\r
+       odDirektoraDoSpremacice(cvor.desno, put);\r
+       put.remove(put.size() - 1);\r
+    }\r
+}\r
+\r
+// Glavna klasa\r
+public class StabloOsobaProgram {\r
+\r
+       // Glavni program\r
+       public static void main(String[] args) {\r
+\r
+               // Napravimo pomocni objekat za ucitavanje i ispisivanje\r
+               TreeIO<StabloOsoba> io = new TreeIO<>(StabloOsoba.class);\r
+\r
+               // Procitamo stablo iz fajla\r
+               StabloOsoba stablo = io.read(Svetovid.in("Osobe.txt"));\r
+\r
+               // Ispisemo ucitano stablo\r
+               io.print(Svetovid.out, stablo);\r
+\r
+               // Osoba koju cemo traziti u stablu \r
+               Osoba osobaX = new Osoba("Nikola", "Nikolic-Nikolic", 0);\r
+\r
+               // Broj osoba\r
+               int br = stablo.brojOsoba();\r
+               Svetovid.out.println();\r
+               Svetovid.out.println("Broj osoba u firmi: " + br);\r
+\r
+               // Stampanje svih osoba\r
+               Svetovid.out.println();\r
+               Svetovid.out.println("Te osobe su: ");\r
+               stablo.stampajSveOsobe();\r
+\r
+               // Preuzimanje osoba u listu\r
+           List<Osoba> sveOsobe = stablo.sveOsobe();\r
+               Svetovid.out.println();\r
+               Svetovid.out.println("Ili kako lista: " + sveOsobe);\r
+\r
+           // Podstablo sa Nikolom kao korenom\r
+           StabloOsoba podstablo = stablo.pronadji(osobaX);\r
+               Svetovid.out.println();\r
+               Svetovid.out.println(osobaX + " i podredjeni:");\r
+               io.print(Svetovid.out, podstablo);\r
+\r
+           // Ko je Nikolin sef\r
+       Svetovid.out.println();\r
+           Osoba sef = stablo.sefOd(osobaX);\r
+           if (sef != null) {\r
+               Svetovid.out.println("Sef od " + osobaX + " je " + sef);\r
+           } else {\r
+               Svetovid.out.println(osobaX + " je direktor");\r
+           }\r
+\r
+           // Plate\r
+           int plata = podstablo.getDirektor().getPlata();\r
+               Svetovid.out.println();\r
+       Svetovid.out.println("Plata od " + podstablo.getDirektor() + " je " + plata + "din");\r
+           List<Osoba> sviSaPlatomIspod = stablo.sviSaPlatomIspod(plata);\r
+               Svetovid.out.println();\r
+       Svetovid.out.println("Svi koji imaju platu manju od " + podstablo.getDirektor() + " su: " + sviSaPlatomIspod);\r
+\r
+       // Podredjeni\r
+           List<Osoba> sviPodredjeni = stablo.sviPodredjeni(osobaX);\r
+               Svetovid.out.println();\r
+       Svetovid.out.println("Svi koji podredjeni od " + podstablo.getDirektor() + " su: " + sviPodredjeni);\r
+\r
+           // Struktura firme od diroktora do svakog zaposlenog koji nema podredjene\r
+               Svetovid.out.println();\r
+               Svetovid.out.println("Hijerarhija sefova za svakog zaposlenog koji nema svoje podredjene:");\r
+           stablo.odDirektoraDoSpremacice();\r
+\r
+       }\r
+}\r
diff --git a/Stabla/konkretnoStablo/TreeIO.java b/Stabla/konkretnoStablo/TreeIO.java
new file mode 100644 (file)
index 0000000..23ed58c
--- /dev/null
@@ -0,0 +1,653 @@
+\r
+import java.lang.reflect.Constructor;\r
+import java.lang.reflect.Field;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.lang.reflect.Method;\r
+import java.lang.reflect.Modifier;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.svetovid.io.SvetovidReader;\r
+import org.svetovid.io.SvetovidWriter;\r
+\r
+public class TreeIO<T> {\r
+\r
+    public TreeIO(Class<T> type) {\r
+        this(type, null);\r
+    }\r
+\r
+    ////////////\r
+    // Config //\r
+    ////////////\r
+\r
+    public static class Config {\r
+\r
+        public final String nullSymbol;\r
+        public final int separation;\r
+        public final int length;\r
+\r
+        public Config() {\r
+               this(null, 1, 7);\r
+        }\r
+\r
+               public Config(String nullSymbol, int separation, int length) {\r
+                       this.nullSymbol = nullSymbol;\r
+                       this.separation = separation;\r
+                       this.length = length;\r
+               }\r
+\r
+               public Config setNullSymbol(String nullSymbol) {\r
+                       return new Config(nullSymbol, separation, length);\r
+               }\r
+\r
+               public Config setSeparation(int separation) {\r
+                       return new Config(nullSymbol, separation, length);\r
+               }\r
+               \r
+               public Config setLength(int length) {\r
+                       return new Config(nullSymbol, separation, length);\r
+               }\r
+    }\r
+\r
+       protected Config config;\r
+\r
+    public Config getConfig() {\r
+               return config;\r
+       }\r
+\r
+       public void setConfig(Config config) {\r
+               this.config = config;\r
+       }\r
+\r
+       //////////////\r
+       // Printing //\r
+       //////////////\r
+\r
+    public void print(SvetovidWriter out, T tree) {\r
+       Object root = getRoot(tree);\r
+        StringBuilder builder = new StringBuilder();\r
+        appendTree(builder, root, config);\r
+        out.print(builder.toString());\r
+    }\r
+\r
+       protected void appendTree(StringBuilder builder, Object tree, Config config) {\r
+        String[] buildingBlocks = generateBuildingBlocks(config);\r
+        appendRight(builder, tree, config, buildingBlocks, true, buildingBlocks[5]);\r
+        appendNode(builder, tree, config, buildingBlocks[4]);\r
+        appendLeft(builder, tree, config, buildingBlocks, false, buildingBlocks[5]);\r
+    }\r
+\r
+    protected void appendNode(StringBuilder builder, Object tree, Config config, String prefix) {\r
+        builder.append(prefix);\r
+        if (tree == null) {\r
+            builder.append(config.nullSymbol == null ? VERTICAL_SYMBOL : config.nullSymbol);\r
+        } else {\r
+            builder.append("(o)");\r
+            Object element = getElement(tree);\r
+            if (element != null) {\r
+                builder.append(" ");\r
+                builder.append(element.toString());\r
+            }\r
+        }\r
+        builder.append("\n");\r
+    }\r
+\r
+       protected void appendRight(StringBuilder builder, Object tree, Config config, String[] buildingBlocks, boolean isRight, String prefix) {\r
+        if (tree == null) {\r
+            return;\r
+        }\r
+        Object subtree = getRight(tree);\r
+        if ((config.nullSymbol != null) || (subtree != null)) {\r
+            appendSubtree(builder, subtree, config, buildingBlocks, true, prefix);\r
+            for (int i = 0; i < config.separation; i++) {\r
+                appendEmpty(builder, buildingBlocks, prefix);\r
+            }\r
+        }\r
+    }\r
+\r
+       protected void appendLeft(StringBuilder builder, Object tree, Config config, String[] buildingBlocks, boolean isRight, String prefix) {\r
+        if (tree == null) {\r
+            return;\r
+        }\r
+        Object subtree = getLeft(tree);\r
+        if ((config.nullSymbol != null) || (subtree != null)) {\r
+            for (int i = 0; i < config.separation; i++) {\r
+                appendEmpty(builder, buildingBlocks, prefix);\r
+            }\r
+            appendSubtree(builder, subtree, config, buildingBlocks, false, prefix);\r
+        }\r
+    }\r
+\r
+       protected void appendEmpty(StringBuilder builder, String[] buildingBlocks, String prefix) {\r
+        builder.append(prefix);\r
+        builder.append(buildingBlocks[2]);\r
+        builder.append("\n");\r
+    }\r
+\r
+    protected void appendSubtree(StringBuilder builder, Object tree, Config config, String[] buildingBlocks, boolean isRight, String prefix) {\r
+        String myPrefix = prefix;\r
+        if (isRight == true) {\r
+               myPrefix = myPrefix + buildingBlocks[1];\r
+        }\r
+        if (isRight == false) {\r
+               myPrefix = myPrefix + buildingBlocks[3];\r
+        }\r
+        String noviPrefix = prefix + (!isRight ? buildingBlocks[2] : buildingBlocks[0]);\r
+        appendRight(builder, tree, config, buildingBlocks, isRight, noviPrefix);\r
+        appendNode(builder, tree, config, myPrefix);\r
+        noviPrefix = prefix + (isRight ? buildingBlocks[2] : buildingBlocks[0]);\r
+        appendLeft(builder, tree, config, buildingBlocks, isRight, noviPrefix);\r
+    }\r
+\r
+    protected static final String EMPTY_SYMBOL = " ";\r
+    protected static final String RIGHT_SYMBOL = "/";\r
+    protected static final String VERTICAL_SYMBOL = "|";\r
+    protected static final String LEFT_SYMBOL = "\\";\r
+    protected static final String HORIZONTAL_SYMBOL = "-";\r
+\r
+    protected String[] generateBuildingBlocks(Config config) {\r
+        String[] blocks = new String[6];\r
+        blocks[0] = generateBlock(EMPTY_SYMBOL, EMPTY_SYMBOL, EMPTY_SYMBOL, config.length - 2);\r
+        blocks[1] = generateBlock(EMPTY_SYMBOL, RIGHT_SYMBOL, HORIZONTAL_SYMBOL, config.length - 2);\r
+        blocks[2] = generateBlock(EMPTY_SYMBOL, VERTICAL_SYMBOL, EMPTY_SYMBOL, config.length - 2);\r
+        blocks[3] = generateBlock(EMPTY_SYMBOL, LEFT_SYMBOL, HORIZONTAL_SYMBOL, config.length - 2);\r
+        blocks[4] = HORIZONTAL_SYMBOL;\r
+        blocks[5] = EMPTY_SYMBOL;\r
+        return blocks;\r
+    }\r
+\r
+    protected String generateBlock(String emptySymbol, String startSymbol, String repeatSymbol, int repeatCount) {\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append(emptySymbol);\r
+        builder.append(startSymbol);\r
+        for (int i = 0; i < repeatCount; i++) {\r
+            builder.append(repeatSymbol);\r
+        }\r
+        return builder.toString();\r
+    }\r
+\r
+       /////////////\r
+       // Reading //\r
+       /////////////\r
+\r
+       public T read(SvetovidReader in) {\r
+               return newTree(parseTree(in, config)); \r
+    }\r
+\r
+       protected Object parseTree(SvetovidReader in, Config config) {\r
+               List<Object> elements = new ArrayList<>();\r
+               List<Integer> levels = new ArrayList<>();\r
+               Pattern levelPattern = Pattern.compile("[\\Q" + LEFT_SYMBOL + HORIZONTAL_SYMBOL + RIGHT_SYMBOL + "\\E]");\r
+               String line = in.readLine();\r
+               while ((line != null) && !line.isEmpty()) {\r
+                       Matcher matcher = levelPattern.matcher(line);\r
+                       int level = -1;\r
+                       if (matcher.find()) {\r
+                               level = matcher.start();\r
+                       }\r
+                       if (level != -1 && (config.nullSymbol == null || !line.endsWith(config.nullSymbol))) {\r
+                               Object tree = parseTree(line);\r
+                               elements.add(tree);\r
+                               levels.add(level);\r
+                       }\r
+                       line = in.readLine();\r
+               }\r
+               Object tree = formTree(0, elements.size(), levels, elements);\r
+               return tree;\r
+       }\r
+\r
+       protected Object parseTree(String line) {\r
+               String value;\r
+               int beginIndex = line.indexOf('(');\r
+               int endIndex = line.indexOf(')');\r
+               if ((beginIndex != -1) && (endIndex != -1) && (beginIndex < endIndex)) {\r
+                       value = line.substring(endIndex + 1);\r
+                       if (value.length() == 0) {\r
+                               value = null;\r
+                       } else {\r
+                               value = value.substring(1);\r
+                       }\r
+               } else {\r
+                       throw new NumberFormatException(line);\r
+               }\r
+               Object element = null;\r
+               if (value != null) {\r
+                       element = newElement(value);\r
+               }\r
+               Object tree = newNode(element);\r
+               return tree;\r
+       }\r
+\r
+       protected Object formTree(int beginIndex, int endIndex, List<Integer> levels, List<Object> elements) {\r
+               if (beginIndex >= endIndex) {\r
+                       return null;\r
+               }\r
+               int minIndex = beginIndex;\r
+               int minLevel = levels.get(minIndex);\r
+               for (int i = beginIndex + 1; i < endIndex; i++) {\r
+                       int level = levels.get(i);\r
+                       if (level < minLevel) {\r
+                               minLevel = level;\r
+                               minIndex = i;\r
+                       }\r
+               }\r
+               Object tree = elements.get(minIndex);\r
+               Object left = formTree(minIndex + 1, endIndex, levels, elements);\r
+               Object right = formTree(beginIndex, minIndex, levels, elements);\r
+               setLeft(tree, left);\r
+               setRight(tree, right);\r
+               return tree;\r
+       }\r
+\r
+       ///////////\r
+       // Magic //\r
+       ///////////\r
+\r
+    @SuppressWarnings("unchecked")\r
+       public TreeIO(Class<T> type, Config config) {\r
+\r
+       // Tree type\r
+       if (type == null) {\r
+               throw new IllegalArgumentException("Prosledjena klasa je null");\r
+       }\r
+       this.treeType = type;\r
+               if (Modifier.isAbstract(this.treeType.getModifiers())) {\r
+               throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " ne sme da bude apstraktna");\r
+               }\r
+\r
+       // Node type\r
+       Class<?>[] declaredClasses = treeType.getDeclaredClasses();\r
+       if (declaredClasses.length == 0) {\r
+               throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " nema unutrasnju klasu koja predstavlja cvorove");\r
+       }\r
+       Class<?> staticOne = null;\r
+       boolean multiStatic = false;\r
+       for (Class<?> cl: declaredClasses) {\r
+           if (Modifier.isStatic(cl.getModifiers())) {\r
+               if (staticOne == null) {\r
+                   staticOne = cl;\r
+               } else {\r
+                   multiStatic = true;\r
+               }\r
+           }\r
+       }\r
+       if (staticOne == null) {\r
+               throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " nema staticku unutrasnju klasu koja predstavlja cvorove");\r
+       }\r
+       if (multiStatic) {\r
+               throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " ima vise unutrasnjih statickih klasa, a mora biti samo jedna");\r
+       }\r
+               this.nodeType = staticOne;\r
+               if (Modifier.isAbstract(this.nodeType.getModifiers())) {\r
+               throw new IllegalArgumentException("Klasa " + this.nodeType.getName() + " ne sme da bude apstraktna");\r
+               }\r
+               if (!Modifier.isStatic(this.nodeType.getModifiers())) {\r
+               throw new IllegalArgumentException("Klasa " + this.nodeType.getName() + " mora da bude staticka");\r
+               }\r
+\r
+               // Tree constructors\r
+               Constructor<?>[] declaredConstructors = this.treeType.getDeclaredConstructors();\r
+               Constructor<T> defaultTreeConstructor = null;\r
+               Constructor<T> treeConstructor = null;\r
+               for (Constructor<?> constructor : declaredConstructors) {\r
+                       boolean throwingExceptions = false;\r
+                       for (Class<?> exception : constructor.getExceptionTypes()) {\r
+                               if (!RuntimeException.class.isAssignableFrom(exception)) {\r
+                                       throwingExceptions = true;\r
+                               }\r
+                       }\r
+                       Class<?>[] parameters = constructor.getParameterTypes();\r
+                       if (parameters.length == 0\r
+                                       && !throwingExceptions) {\r
+                               defaultTreeConstructor = (Constructor<T>) constructor;\r
+                       }\r
+                       if (parameters.length == 1\r
+                                       && parameters[0].isAssignableFrom(this.nodeType)\r
+                                       && !throwingExceptions) {\r
+                               treeConstructor = (Constructor<T>) constructor;\r
+                       }\r
+               }\r
+               if (defaultTreeConstructor == null && treeConstructor == null) {\r
+                       throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " nema "\r
+                                       + this.nodeType.getSimpleName() + "() ili "\r
+                                       + this.nodeType.getSimpleName() + "(" + this.nodeType.getName() + ") konstruktor");\r
+               }\r
+               this.defaultTreeConstructor = defaultTreeConstructor;\r
+               if (this.defaultTreeConstructor != null) {\r
+                       this.defaultTreeConstructor.setAccessible(true);\r
+               }\r
+               this.treeConstructor = treeConstructor;\r
+               if (this.treeConstructor != null) {\r
+                       this.treeConstructor.setAccessible(true);\r
+               }\r
+\r
+               // Tree root field\r
+               Field[] declaredFields = this.treeType.getDeclaredFields();\r
+       Field rootField = null;\r
+       for (Field field : declaredFields) {\r
+               if (Modifier.isStatic(field.getModifiers())) {\r
+                       continue;\r
+               }\r
+               if (field.getType().isAssignableFrom(this.nodeType)) {\r
+                       if (rootField != null) {\r
+                       throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " ima vise polja koji bi mogli predstavljati koren stabla");\r
+                       }\r
+                       rootField = field;\r
+               }\r
+       }\r
+               if (rootField == null) {\r
+               throw new IllegalArgumentException("Klasa " + this.treeType.getName() + " nema polje za predstavljanje korena");\r
+               }\r
+               this.rootField = rootField;\r
+               if (Modifier.isStatic(this.rootField.getModifiers())) {\r
+               throw new IllegalArgumentException("Polje " + this.treeType.getName() + "." + this.rootField.getName() + " ne sme da bude staticko");\r
+               }\r
+               this.rootField.setAccessible(true);\r
+\r
+       // Node fields\r
+       declaredFields = this.nodeType.getDeclaredFields();\r
+       if (declaredFields.length == 0) {\r
+               throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema deklarisanih polja");\r
+       }\r
+       Field elementField = null;\r
+       Field leftField = null;\r
+       Field rightField = null;\r
+       for (Field field : declaredFields) {\r
+               if (Modifier.isStatic(field.getModifiers())) {\r
+                       continue;\r
+               }\r
+               String fieldName = field.getName();\r
+               if (fieldName.startsWith("e") || fieldName.startsWith("i") || fieldName.startsWith("o")) {\r
+                       if (elementField != null) {\r
+                       throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " ima vise polja za predstavljanje elementa");\r
+                       }\r
+                       elementField = field;\r
+               }\r
+               if (fieldName.startsWith("l")\r
+                               && field.getType().isAssignableFrom(this.nodeType)) {\r
+                       if (leftField != null) {\r
+                       throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " ima vise polja za predstavljanje levog podstabla");\r
+                       }\r
+                       leftField = field;\r
+               }\r
+               if (fieldName.startsWith("d") || fieldName.startsWith("r")\r
+                               && field.getType().isAssignableFrom(this.nodeType)) {\r
+                       if (rightField != null) {\r
+                       throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " ima vise polja za predstavljanje desnog podstabla");\r
+                       }\r
+                       rightField = field;\r
+               }\r
+       }\r
+               if (elementField == null) {\r
+               throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema polje za predstavljanje elementa");\r
+               }\r
+               if (leftField == null) {\r
+                       throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema polje za predstavljanje levog podstabla");\r
+               }\r
+               if (rightField == null) {\r
+                       throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema polje za predstavljanje desnog podstabla");\r
+               }\r
+               this.elementField = elementField;\r
+               if (Modifier.isStatic(this.elementField.getModifiers())) {\r
+               throw new IllegalArgumentException("Polje " + this.treeType.getName() + "." + this.elementField.getName() + " ne sme da bude staticko");\r
+               }\r
+               this.elementField.getModifiers();\r
+               \r
+               this.elementField.setAccessible(true);\r
+               this.leftField = leftField;\r
+               if (Modifier.isStatic(this.leftField.getModifiers())) {\r
+               throw new IllegalArgumentException("Polje " + this.treeType.getName() + "." + this.leftField.getName() + " ne sme da bude staticko");\r
+               }\r
+               this.leftField.setAccessible(true);\r
+               this.rightField = rightField;\r
+               if (Modifier.isStatic(this.rightField.getModifiers())) {\r
+               throw new IllegalArgumentException("Polje " + this.treeType.getName() + "." + this.rightField.getName() + " ne sme da bude staticko");\r
+               }\r
+               this.rightField.setAccessible(true);\r
+\r
+               // Element type\r
+               this.elementType = elementField.getType();\r
+\r
+               // Node constructors\r
+               declaredConstructors = this.nodeType.getDeclaredConstructors();\r
+               Constructor<?> defaultNodeConstructor = null;\r
+               Constructor<?> nodeConstructor = null;\r
+               Constructor<?> nodeConstructor3 = null;\r
+               for (Constructor<?> constructor : declaredConstructors) {\r
+                       boolean throwingExceptions = false;\r
+                       for (Class<?> exception : constructor.getExceptionTypes()) {\r
+                               if (!RuntimeException.class.isAssignableFrom(exception)) {\r
+                                       throwingExceptions = true;\r
+                               }\r
+                       }\r
+                       Class<?>[] parameters = constructor.getParameterTypes();\r
+                       if (parameters.length == 0\r
+                                       && !throwingExceptions) {\r
+                               defaultNodeConstructor = constructor;\r
+                       }\r
+                       if (parameters.length == 1\r
+                                       && parameters[0].isAssignableFrom(this.elementType)\r
+                                       && !throwingExceptions) {\r
+                               nodeConstructor = constructor;\r
+                       }\r
+                       if (parameters.length == 3\r
+                                       && parameters[0].isAssignableFrom(this.elementType)\r
+                                       && parameters[1].isAssignableFrom(this.nodeType)\r
+                                       && parameters[2].isAssignableFrom(this.nodeType)\r
+                                       && !throwingExceptions) {\r
+                               nodeConstructor3 = constructor;\r
+                       }\r
+               }\r
+               if (defaultNodeConstructor == null && nodeConstructor == null && nodeConstructor3 == null) {\r
+                       throw new IllegalArgumentException("Unutrasnja klasa " + this.nodeType.getName() + " nema "\r
+                                       + this.nodeType.getSimpleName() + "() ili "\r
+                                       + this.nodeType.getSimpleName() + "(" + this.elementType.getName() + ") ili "\r
+                                       + this.nodeType.getSimpleName() + "(" + this.elementType.getName() + ", " + this.nodeType.getSimpleName() + ", " + this.nodeType.getSimpleName() + ") konstruktor");\r
+               }\r
+               this.defaultNodeConstructor = defaultNodeConstructor;\r
+               if (this.defaultNodeConstructor != null) {\r
+                       this.defaultNodeConstructor.setAccessible(true);\r
+               }\r
+               this.nodeConstructor = nodeConstructor;\r
+               if (this.nodeConstructor != null) {\r
+                       this.nodeConstructor.setAccessible(true);\r
+               }\r
+               this.nodeConstructor3 = nodeConstructor3;\r
+               if (this.nodeConstructor3 != null) {\r
+                       this.nodeConstructor3.setAccessible(true);\r
+               }\r
+\r
+               // Element methods\r
+               Method elementFactoryMethod = null;\r
+               Method[] declaredMethods = this.elementType.getDeclaredMethods();\r
+               for (Method method : declaredMethods) {\r
+               if (!Modifier.isStatic(method.getModifiers())) {\r
+                       continue;\r
+               }\r
+                       boolean throwingExceptions = false;\r
+                       for (Class<?> exception : method.getExceptionTypes()) {\r
+                               if (!RuntimeException.class.isAssignableFrom(exception)) {\r
+                                       throwingExceptions = true;\r
+                               }\r
+                       }\r
+                       String methodName = method.getName();\r
+                       boolean familiarName = methodName.equals("fromString")\r
+                                       || methodName.equals("valueOf")\r
+                                       || methodName.equals("parse" + this.elementType.getSimpleName());\r
+                       boolean goodParameters = method.getParameterTypes().length == 1 && (method.getParameterTypes()[0] == String.class || method.getParameterTypes()[0] == Object.class);\r
+                       if (familiarName\r
+                                       && goodParameters\r
+                                       && this.elementType.isAssignableFrom(method.getReturnType())\r
+                                       && !throwingExceptions) {\r
+                               if (elementFactoryMethod != null) {\r
+                       throw new IllegalArgumentException("Klasa " + this.elementType.getName() + " ima vise "\r
+                                       + this.elementType.getSimpleName() + " fromString(String), "\r
+                                       + this.elementType.getSimpleName() + " valueOf(String) i "\r
+                                       + this.elementType.getSimpleName() + " parse" + this.elementType.getSimpleName() + "(String) metoda");\r
+                               }\r
+                               elementFactoryMethod = method;\r
+                       }\r
+               }\r
+               if (elementFactoryMethod == null) {\r
+               throw new IllegalArgumentException("Klasa " + this.elementType.getName() + " nema "\r
+                               + this.elementType.getSimpleName() + " fromString(String), "\r
+                               + this.elementType.getSimpleName() + " valueOf(String) ili "\r
+                               + this.elementType.getSimpleName() + " parse" + this.elementType.getSimpleName() + "(String) metod");\r
+               }\r
+               this.elementFactoryMethod = elementFactoryMethod;\r
+               this.elementFactoryMethod.setAccessible(true);\r
+\r
+       // Config\r
+       if (config == null) {\r
+               config = new Config();\r
+       }\r
+       this.config = config;\r
+\r
+    }\r
+\r
+       protected final Class<T> treeType;\r
+    protected final Constructor<T> treeConstructor;\r
+    protected final Constructor<T> defaultTreeConstructor;\r
+    protected final Field rootField;\r
+    protected final Class<?> nodeType;\r
+    protected final Field elementField;\r
+    protected final Field leftField;\r
+    protected final Field rightField;\r
+    protected final Constructor<?> nodeConstructor3;\r
+    protected final Constructor<?> nodeConstructor;\r
+    protected final Constructor<?> defaultNodeConstructor;\r
+    protected final Class<?> elementType;\r
+    protected final Method elementFactoryMethod;\r
+\r
+    private Object getRoot(T tree) {\r
+               try {\r
+                       Object value = rootField.get(tree);\r
+                       return value;\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               }\r
+       }\r
+    \r
+    private void setRoot(T tree, Object root) {\r
+               try {\r
+                       rootField.set(tree, root);\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+               }\r
+       }\r
+\r
+    private Object getElement(Object node) {\r
+               try {\r
+                       Object value = elementField.get(node);\r
+                       return value;\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               }\r
+       }\r
+    \r
+    private void setElement(Object node, Object value) {\r
+               try {\r
+                       elementField.set(node, value);\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+               }\r
+       }\r
+\r
+    private Object getLeft(Object node) {\r
+               try {\r
+                       Object value = leftField.get(node);\r
+                       return value;\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               }\r
+       }\r
+\r
+    private void setLeft(Object node, Object value) {\r
+               try {\r
+                       leftField.set(node, value);\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+               }\r
+       }\r
+\r
+    private Object getRight(Object node) {\r
+               try {\r
+                       Object value = rightField.get(node);\r
+                       return value;\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               }\r
+       }\r
+\r
+    private void setRight(Object node, Object value) {\r
+               try {\r
+                       rightField.set(node, value);\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+               }\r
+       }\r
+\r
+       private Object newElement(String value) {\r
+               try {\r
+                       return elementFactoryMethod.invoke(null, value);\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               } catch (InvocationTargetException e) {\r
+                       // Will not be a checked exception\r
+                       RuntimeException cause = (RuntimeException) e.getCause();\r
+                       throw cause;\r
+               }\r
+       }\r
+\r
+       private Object newNode(Object element) {\r
+               try {\r
+                       if (nodeConstructor != null) {\r
+                               return nodeConstructor.newInstance(element);\r
+                       }\r
+                       if (nodeConstructor3 != null) {\r
+                               return nodeConstructor3.newInstance(element, null, null);\r
+                       }\r
+                       Object node = defaultNodeConstructor.newInstance();\r
+                       setElement(node, element);\r
+                       return node;\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               } catch (InstantiationException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               } catch (InvocationTargetException e) {\r
+                       // Will not be a checked exception\r
+                       RuntimeException cause = (RuntimeException) e.getCause();\r
+                       throw cause;\r
+               }\r
+       }\r
+\r
+       private T newTree(Object root) {\r
+               try {\r
+                       if (treeConstructor != null) {\r
+                               return treeConstructor.newInstance(root);\r
+                       }\r
+                       T tree = defaultTreeConstructor.newInstance();\r
+                       setRoot(tree, root);\r
+                       return tree;\r
+               } catch (IllegalAccessException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               } catch (InstantiationException e) {\r
+                       // Will never happen\r
+                       return null;\r
+               } catch (InvocationTargetException e) {\r
+                       // Will not be a checked exception\r
+                       RuntimeException cause = (RuntimeException) e.getCause();\r
+                       throw cause;\r
+               }\r
+       }\r
+}\r
diff --git a/Stabla/konkretnoStablo/Zadatak.txt b/Stabla/konkretnoStablo/Zadatak.txt
new file mode 100644 (file)
index 0000000..ad6a25b
--- /dev/null
@@ -0,0 +1,100 @@
+Zadatak\r
+=======\r
+\r
+Data je klasa koja implementira binarno stablo osoba.\r
+Takodje, je dat i glavni program koji ucitava jedno stablo i\r
+poziva neke od operacija nad njim.\r
+\r
+Implementirati operacije navedene u nastavku i ilustrovati\r
+njihov rad pozivanjem iz glavnog programa. Svaki metod je\r
+potrebno implementirati kao javan metod klase koja\r
+predstavlja stablo, a po potrebi se definisu pomocni\r
+staticki metodi koji ce rekurzivno obilaziti stablo. Pomocni\r
+metodi ce cesto biti istog imena kao i glavni metod.\r
+\r
+Primer implementacije metoda i njihovih poziva postoji u\r
+`StabloOsobaProgram.java`.\r
+\r
+Preporucuje se da se zadati metodi dodaju u\r
+`MinimalnoStablo.java`, mada ih je moguce dodavati i u\r
+`StabloOsobaProgram.java` ili `MojeStablo.java`.\r
+\r
+\r
+Metodi\r
+======\r
+\r
+\r
+public double prosecnaPlata()\r
+-----------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+izracunava i vraca prosecnu platu svih zaposlenih.\r
+\r
+Ako je stablo prazno, prosecna plata je 0.0.\r
+\r
+\r
+public Osoba osobaSaNajvecomPlatom()\r
+------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+pronalazi i vraca osobu koja ima najvecu platu.\r
+\r
+\r
+public List<Osoba> sviPodredjeni(Osoba o)\r
+-----------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+vraca listu svih zaposlenih koji su podredjeni\r
+datoj osobi.\r
+\r
+Lista ne ukljucuje prosledjenu osobu.\r
+\r
+Ako je stablo prazno, ili se osoba ne nalazi u\r
+stablu, vratiti praznu listu.\r
+\r
+\r
+public List<Osoba> sviNadredjeni(Osoba o)\r
+-----------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+vraca listu svih nadredjenih datoj osobi pocevsi\r
+od generalnog direktora.\r
+\r
+\r
+public List<Osoba> sviSaIstomPlatom()\r
+-------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+pronalazi i vraca sve osobe koje imaju platu\r
+istu kao jos neka druga osoba.\r
+\r
+\r
+public void ispisiOsobeSaVecomPlatomOdSefa()\r
+--------------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+ispisuje sve osobe koje imaju vecu platu od svog sefa.\r
+\r
+\r
+public List<Osoba> vecaPlataOdDirektora()\r
+-----------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+vraca listu svih zaposlenih koji imaju vecu\r
+platu od generalnog direktora (koren celog stabla).\r
+\r
+\r
+public List<Osoba> plataIspodProseka()\r
+--------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+vraca listu svih zaposlenih koji imaju platu ispod\r
+proseka u firmi.\r
+\r
+\r
+public Osoba drugaPoReduSaNajvecomPlatom()\r
+------------------------------------------\r
+\r
+U klasi StabloOsoba, implementirati metod koji\r
+pronalazi i vraca osobu koja je druga po redu\r
+po velicini plate.\r
Svarog.pmf.uns.ac.rs/gitweb maintanance Doni Pracner