gitweb on Svarog

projekti pod git sistemom za održavanje verzija -- projects under the git version control system
Skup v1.1.1
[spa1-materijali.git] / kodovi / skup / Skup.java
1 import java.lang.reflect.Array;
3 /**
4 * Tip podataka skup - predstavlja kolekciju razlicitih objekata zadatog tipa.
5 * Svi metodi garantuju da ce svi elementi u skupu biti razlicitu u skladu sa
6 * svojim {@code equals} metodom. Specijalno {@code null} ne moze biti element
7 * skupa. Skup je interno realizovan preko kruzne liste sa zaglavljem.
8 *
9 * <p>
10 * Pomocni materijal na kursu SPA1, DMI, PMF, UNS www.dmi.rs
11 * </p>
12 *
13 * <p>
14 * <strong>v1.1.1</strong>
15 * </p>
16 *
17 * @param <T>
18 * tip podataka koji ce biti skladisten u instanci ove klase.
19 */
20 public class Skup<T> {
22 /**
23 * Pojedinacni element u skupu, sadrzi pokazivac na sledeci element i
24 * informaciju o podatku koji se cuva.
25 *
26 */
27 class Element {
28 T info;
29 Element veza;
31 /**
32 * Kreira nov prazan element.
33 */
34 public Element() {
35 this(null);
36 }
38 /**
39 * Kreira element u kome se cuva prosledjeni {@code podatak}
40 *
41 * @param podatak
42 * informacija koja ce biti sacuvana u ovom elementu.
43 */
44 public Element(T podatak) {
45 this.info = podatak;
46 this.veza = null;
47 }
49 }
51 Element zaglavlje;
53 // brojac elemenata u skupu
54 int brojac;
56 /**
57 * Kreira nov prazan skup.
58 */
59 public Skup() {
60 zaglavlje = new Element();
61 zaglavlje.veza = zaglavlje;
62 brojac = 0;
63 }
65 public String toString() {
66 String rezultat = "Skup {";
67 Element tekuci = zaglavlje.veza;
68 if (tekuci != zaglavlje) {
69 rezultat += " " + tekuci.info;
70 tekuci = tekuci.veza;
71 }
72 while (tekuci != zaglavlje) {
73 rezultat += ", " + tekuci.info;
74 tekuci = tekuci.veza;
75 }
76 return rezultat + " }";
77 }
79 /**
80 * Vraca velicinu, odnosno broj elemenata skupa.
81 *
82 * @return broj elemenata skupa
83 */
84 public int velicina() {
85 return brojac;
86 }
88 /**
89 * Vraca da li je skup prazan, odnosno da li u njemu ima elemenata.
90 *
91 * @return da li u skupu ima elemenata
92 */
93 public boolean jePrazan() {
94 return brojac == 0;
95 }
97 /**
98 * Vraca da li dati element pripada skupu, a u skladu sa jednakoscu
99 * definisanom u metodu {@code equals} odgovarajuce klase.
100 *
101 * @param clan
102 * podatak za koji se proverava da li je vec u skupu.
103 * @return da li element vec postoji u skupu
104 */
105 public boolean pripada(T clan) {
106 if (clan == null)
107 return false;
109 zaglavlje.info = clan;
110 Element tekuci = zaglavlje.veza;
111 while (!tekuci.info.equals(clan)) {
112 tekuci = tekuci.veza;
114 return tekuci != zaglavlje;
117 /**
118 * Dodaje prosledjeni podatak u skup, ukoliko vec nije postoao i vraca da li
119 * ova operacija dodala element u skup. Jednakost elemenata se posmatra na
120 * osnovu metoda {@code equals} odgovarajuce klase. Specijalno {@code null}
121 * ne moze biti element skupa i bice vraceno false posto element nije
122 * ubacen, iako takav element nije postojao u skupu.
123 *
124 * @param clan
125 * podatak koji se zeli ubaciti u skup
126 * @return da li je element uspesno ubacen
127 */
128 public boolean ubaci(T clan) {
129 // ne mozemo ubaciti null element
130 if (clan == null)
131 return false;
132 if (!pripada(clan)) {
133 Element novi = new Element();
134 novi.info = clan;
135 novi.veza = zaglavlje.veza;
136 zaglavlje.veza = novi;
137 brojac++;
138 return true;
139 } else {
140 return false;
144 /**
145 * Izbacuje prosledjeni podatak iz skupa, ukoliko on je bio u skupu.
146 * Jednakost elemenata se posmatra na osnovu metoda {@code equals}
147 * odgovarajuce klase.
148 *
149 * @param clan
150 * podatak koji se zeli izbaciti iz skupa
151 * @return da li je element uspesno izbacen
152 */
153 public boolean izbaci(T clan) {
154 // ne mozemo ubaciti null element
155 if (clan == null)
156 return false;
157 zaglavlje.info = clan;
158 Element prethodni = zaglavlje;
159 while (!prethodni.veza.info.equals(clan)) {
160 prethodni = prethodni.veza;
162 if (prethodni.veza != zaglavlje) {
163 prethodni.veza = prethodni.veza.veza;
164 brojac--;
165 return true;
166 } else {
167 return false;
171 /**
172 * Dodaje sve elemente prosledjenog skupa u ovaj skup, odnosno one koji vec
173 * nisu bili u skupu. Jednakost elemenata se posmatra na osnovu metoda
174 * {@code equals} odgovarajuce klase.
175 *
176 * @param skup
177 * skup iz koga se zele ubaciti svi elementi u ovaj skup
178 */
179 public void ubaciSve(Skup<T> skup) {
180 if (skup == null)
181 return;
183 Element tekuci = skup.zaglavlje.veza;
184 while (tekuci != skup.zaglavlje) {
185 ubaci(tekuci.info);
186 tekuci = tekuci.veza;
190 /**
191 * Vraca novi skup koji je jednak uniji ovog skupa i prosledjenog
192 * skupa.Tacnije poziv {@code a.unija(b)} je matematicki ekvivalentan sa:
193 *
194 * <pre>
195 * a &cup; b
196 * </pre>
197 *
198 *
199 * @param drugi
200 * skup sa kojim se pravi unija
201 * @return novi skup koji je unija ovog i prosledjenog skupa
202 */
203 public Skup<T> unija(Skup<T> drugi) {
204 Skup<T> rezultat = new Skup<T>();
205 rezultat.ubaciSve(this);
206 rezultat.ubaciSve(drugi);
207 return rezultat;
210 /**
211 * Vraca novi skup koji predstavlja presek ovog i prosledjenog skupa.Tacnije
212 * poziv {@code a.presek(b)} je matematicki ekvivalentan sa:
213 *
214 * <pre>
215 * a &cap; b
216 * </pre>
217 *
218 * Specijalno ako je drugi skup {@code null} bice tumacen kao prazan skup,
219 * odnosno i rezultat ce biti prazan skup.
220 *
221 * @param drugi
222 * skup sa kojim se pravi presek.
223 * @return presek ova dva skupa
224 */
225 public Skup<T> presek(Skup<T> drugi) {
226 Skup<T> rezultat = new Skup<T>();
227 if (drugi != null) {
228 Element tekuci = zaglavlje.veza;
229 while (tekuci != zaglavlje) {
230 if (drugi.pripada(tekuci.info)) {
231 rezultat.ubaci(tekuci.info);
233 tekuci = tekuci.veza;
236 return rezultat;
239 /**
240 * Vraca novi skup koji predstavlja razliku ovog i prosledjenog skupa.
241 * Tacnije od ovog skupa ce biti oduzeti elementi prosledjenog, tj poziv
242 * {@code a.razlika(b)} je matematicki ekvivalentan sa:
243 *
244 * <pre>
245 * a \ b
246 * </pre>
247 *
248 * Specijalno ako je drugi skup {@code null} bice tumacen kao prazan skup,
249 * odnosno rezultat ce biti jednak ovom skupu.
250 *
251 * @param drugi
252 * skup koji se oduzima
253 * @return razlika ovog skupa i prosledjenog
254 */
255 public Skup<T> razlika(Skup<T> drugi) {
256 Skup<T> rezultat = new Skup<T>();
257 if (drugi != null) {
258 Element tekuci = zaglavlje.veza;
260 while (tekuci != zaglavlje) {
261 if (!drugi.pripada(tekuci.info)) {
262 rezultat.ubaci(tekuci.info);
264 tekuci = tekuci.veza;
266 } else
267 rezultat.ubaciSve(this);
268 return rezultat;
271 /**
272 * Vraca da li je ovaj skup podskup prosledjenog skupa. Tacnije poziv
273 * {@code a.podskup(b)} je matematicki ekvivalentan sa:
274 *
275 * <pre>
276 * a &sube; b
277 * </pre>
278 *
279 * Specijalno ako je drugi skup {@code null} bice tumacen kao prazan skup,
280 * odnosno i rezultat ce biti {@code true} samo ako je i ovaj skup prazan.
281 *
282 * @param drugi
283 * skup za koji se proverava da li je ovaj podskup
284 * @return da li je ovaj skup podskup prosledjenog skupa
285 */
286 public boolean podskupOd(Skup<T> drugi) {
287 if (drugi == null)
288 return brojac == 0;
289 Element tekuci = zaglavlje.veza;
290 while (tekuci != zaglavlje) {
291 if (!drugi.pripada(tekuci.info)) {
292 return false;
294 tekuci = tekuci.veza;
296 return true;
299 /**
300 * Vraca niz koji se sastoji od elemenata koji su trenutno u skupu. Ukoliko
301 * je u pitanju prazan skup vratice {@code null}, tako da je pozeljno
302 * proveriti pre poziva metoda da li je skup velicine 0, ili naknadno
303 * proveravati da li je dobijena vrednost null.
304 *
305 * @return niz koji predstavlja elemente skupa, ili null ako je skup prazan
306 */
307 public T[] napraviNiz() {
308 if (brojac > 0) {
309 // zbog prisustva opstih tipova, niz se pravi na komplikovaniji
310 // nacin nego inace
311 @SuppressWarnings("unchecked")
312 T[] rez = (T[]) Array
313 .newInstance(zaglavlje.info.getClass(), brojac);
315 int i = 0;
316 Element tekuci = zaglavlje.veza;
317 while (tekuci != zaglavlje) {
318 rez[i++] = tekuci.info;
319 tekuci = tekuci.veza;
321 return rez;
322 } else {
323 return null;
Svarog.pmf.uns.ac.rs/gitweb maintanance Doni Pracner