You are on page 1of 37

3.

STRUKTURE PODATAKA

3.1. Elementi od kojih se grade strukture podataka


Struktura podataka se sastoji od manjih cjelina koje se udružuju u veće i međusobno
povezuju vezama.
Uvodimo posebne nazive za cjeline, načine udruživanja i načine povezivanja. Također,
uvodimo pravila kako se strukture prikazuju dijagramima.
Ćelija . . . varijabla koju promatramo kao zasebnu cjelinu. Svaka ćelija ima svoj tip i adresu.

Polje . . . (array u C++-u). Mehanizam udruživanja manjih dijelova strukture u veće. Polje čini
više ćelija istog tipa pohranjenih na uzastopnim adresama. Broj ćelija je unaprijed zadan i
nepromjenljiv.
Jedna ćelija se zove element polja i jednoznačno je određena pripadnom vrijednošću indeksa.
Po ugledu na C++, uzimamo da su indeksi 0, 1, 2, ... , N-1, gdje je N cjelobrojna konstanta.

Zapis . . . (slog, structure u C++-u). Također mehanizam udruživanja manjih dijelova


strukture u veće. Zapis čini više ćelija, koje ne moraju biti istog tipa, no koje su pohranjene na
uzastopnim adresama. Broj, redosljed i tip ćelija je unaprijed zadan i nepromjenljiv. Pojedina
ćelija se zove komponenta zapisa. Polja i zapisi se mogu kombinirati. Na primjer, možemo
imati polje zapisa, zapis čije pojedine komponente su polja, polje od polja, zapis čija
komponenta je zapis, i slično.

Pointer . . . služi za uspostavljanje veze izmedu dijelova strukture. Pointer ili pokazivač je
ćelija koja pokazuje neku drugu ćeliju. Sadržaj pointera je adresa ćelije koju treba pokazati.
Kursor . . . također služi za uspostavljanje veze izmedu dijelova strukture. Kursor je ćelija
tipa int koja pokazuje na element nekog polja. Sadržaj kursora je indeks elementa kojeg
treba pokazati.

Dijagram ispod pokazuje primjer strukture podataka koja se sastoji od niza zapisa povezanih
pomoću pointera, te od jednog polja zapisa. Zapisi su još međusobno povezani kursorima.

3.2. Podjela struktura podataka


Generalno strukture podataka možemo klasificirati u 2 kategorije prikazane na slici ispod:
➢ Primitivne strukture podataka – osnovne strukture sa kojima se radi direktno sa
mašinskim instrukcija. U ovu grupu spadaju: cijeli brojevi, brojevi sa pomičnim
zarezom, znakovi i pokazivači ili pointeri.
➢ Složene strukture podataka - napredniji oblik grupisanja podataka istog ili različitog
tipa. Kreiraju se od primitivnih tipova podataka. U ovu grupu spadaju: polja, liste,
stabla i grafovi kao i razne varijacije ovih struktura.
Slika 3.1. Klasifikacija struktura podataka

3.2.1. Polja
U programiranju se često susrećemo s upotrebom jednodimenzionalnih polja odnosno
nizova. Korištenjem polja možemo na smislen način grupisati više podataka istoga tipa. Npr.,
želimo li izračunati ali i pohraniti ocjene sa ispita iz nekog predmeta za sve studente koji su
izašli na ispit, jedan od načina je korištenjem polja.
Polje, dakle, predstavlja sljedni niz memorijskih lokacija rezervisan za određeni tip podatka.
Svakom elementu polja možemo pristupiti na temelju indeksnih varijabli. Operacije pristupa
elementima polja zahtjeva O(1) vrijeme.
U ovom dijelu obradit će se osnovni pojmovi iz nizova i stringova u programskom jeziku C++.
To su:
• Deklaracija, inicijalizacija i korištenje jednodimenzionalnih i višedimenzionalnih
nizova.
• Nizovi i funkcije
• Pokazivači i nizovi
• Nizovi karaktera u C-u (C-stringovi)
• Pokazivači na nizove karaktera
• Funkcije za rad sa C-stringovima

3.2.1.1. Jednodimenzionalna polja ili nizovi


Promjenljive sa kojima smo radili do sada mogle su istovremeno da čuvaju samo jednu
vrijednost. Nizovi omogućavaju da koristimo jednu promjenljivu koja će čuvati ogroman broj
podataka. Članovi niza zauzimaju susjedne memorijske lokacije (Slika 3.2.). Adresa sa
najmanjom vrijednošću (najniža adresa) odgovara prvom članu niza dok najviša adresa
odgovara posljednjem članu niza. Članovima niza pristupamo na osnovu indeksa ili kursora
koji označava poziciju člana u nizu. Prvi član niza ima indeks 0 dok se indeks zatim povećava
za jedan za svaki uzastopni član niza. Ustvari, indeks nekog elementa niza govori koliko je taj
element udaljen od prvog elementa niza.

Slika 3.2. Predstavljanje niza u memoriji računara


Korištenje jedne promjenljive za niz, koja čuva 100 vrijednosti, ima mnogo veće pogodnosti
nego korištenje 100 različitih promjenljivih gdje svaka može da čuva samo jednu vrijednost.
Također, mnogo je lakše pratiti promjene jedne u odnosu na 100 različitih promjenljivih.
Najveća pogodnost korištenja nizova je ta što se mogu koristiti petlje (ciklusi) da bi se
pristupilo svakom uzastopnom elementu niza.
Kada je u pitanju rad sa karakterima, često se dešava da se korisnički ulaz u program sastoji
iz više od jednog karaktera. Pojedinačni karakteri se također mogu organizovati u niz. Nizovi
karaktera obično sadrže null karakter kao posljednji član niza. Takvi nizovi karaktera koji na
kraju sadrže null karakter se nazivaju „C-stringovi“. Na kraju lekcije će biti opisane funkcije
koje se koriste za C-stringove.
Predstavljanje niza
Niz je struktura podatka koja služi da se u njoj smjesti kolekcija elemenata istoga tipa i fiksne
je veličine. Deklaracija niza u C++-u ima sljedeći oblik (prvo se navodi tip promjenljive, zatim
ime promjenljive, a u uglastim zagradama [ ] se navodi broj elemenata niza – tj, veličina niza):
Sintaksa :
tip_podatka ime_polja [ veličina_niza ];
Ovo je jednodimenzionalno polje ili niz. Veličina niza (veličina_niza) mora biti pozitivna
cjelobrojna vrijednost (veća od nule) dok tip (tip_podatka) može biti bilo koji validan C/C++
tip podatka (primitivan ili složen).
Primjer niza:
int Ocjene[ 5 ];

Inicijalizacija niza
Inicijalizacija niza je dodjeljivanje vrijednosti elementima niza u istom iskazu u kome se vrši
deklaracija niza.
Inicijalizacija niza se može izvršiti ili član po član, ili je moguće koristiti sljedeći izraz:
int Ocjene[5] = {10, 6,8,7,8};
pri čemu broj vrijednosti unutar vitičastih zagrada { } ne smije biti veći od maksimalnog broja
elemenata niza koji smo naveli u okviru uglastih zagrada [ ]. Može biti manji.
Također je moguće u toku deklaracije izostaviti maksimalnu dimenziju, a samo u okviru
vitičastih zagrada inicijalizovati članove niza, što će automatski setovati maksimalnu veličinu
niza na broj unesenih elemenata. Stoga, ukoliko napišemo:
int Ocjene[] = {10, 6,8,7,8};
kreiraće se potpuno identičan niz kao u prethodnom primjeru, gdje je niz imao 5 elemenata.
U nastavku je dat primjer dodjele vrijednosti odgovarajućem članu niza, kojem naravno
pristupamo preko indeksa:
Ocjene [4] = 8;
Prethodni izraz dodjeljuje petom članu niza vrijednost 8. Kao i u Java-i, indeks niza počinje
sa nulom (Ocjene [0]) dok posljednji član niza ima indeks N-1, gde je sa N označena dimenzija
niza. Na narednoj slici je grafički prikazan niz iz prethodnog primjera:

Slika 3.3. Predstavljanje niza Ocjene u memoriji računara


Operator sizeof () i nizovi
Operator sizeof koristimo za određivanje broja elemenata niza u slučaju kada dimenzija niza
nije navedena u toku inicijalizacije.

int Ocjene[] = { 10,6,8,7,8 }; // deklaracija niza od 5 elemenata


cout << sizeof(Ocjene); // prikazuje 20 (5 elemenata * 4 bajta za svaki)
U programskom jeziku C++ ne postoji direktan način da se ispita kolika je veličina niza ali je
moguće to utvrditi korišćenjem operatora sizeof na sljedeći način:
int nElements = sizeof(Ocjene) / sizeof(Ocjene[0]);
cout << nElements << endl;S

Obzirom da svi elementi niza imaju istu veličinu (pošto se radi o istom tipu podatka),
dijeljenjem ukupne količine memorije niza sa veličinom memorije koja odgovara jednom
elementu niza dobijamo broj elemenata. Pri tome treba koristiti element sa indeksom 0 s
obzirom da niz koji je deklarisan mora imati bar jedan element.

Pristupanje elementu niza


Elementu niza se pristupa preko indeksa koji stoji u uglastim zagradama uz ime niza.
#include<iostream>
#include <cstdlib>
using namespace std;
void main()
{
const int N = 10;
int n[N]; /* n je niz od 10 cjelih brojeva */
int i, j;
for (i = 0; i < N; i++)
{
n[i] = i + 100; /* vrijednost elementa na poziciji i postavi na i + 100 */
}
/* ispis vrijednosti svakog elementa niza */
for (j = 0; j < N; j++)
{
printf("Element[%d] = %d\n", j, n[j]);
}
}

Nakon izvršavanja prethodnog programa, na ekranu ce biti ispisan sljedeći rezultat:

Najčešća greška pri radu sa nizom: IZLAZAK IZ OPSEGA


Izlazak iz opsega je jedna od težih grešaka za otkrivanje a može da izazove ozbiljne probleme
{
const int duzina_niza = 5;
int niz[duzina_niza] = { 6, 8, 2, 4, 9 };
int maxValue = 0;
for (int nIndex = 0; nIndex <= duzina_niza; nIndex++)
if (niz[nIndex] > maxValue)
maxValue = niz[nIndex];
cout << "Max el je " << maxValue << endl;
}

Problem sa prethodnim kodom je taj što je uslovni izraz u okviru for naredbe netačan.
Deklarisani niz ima 5 elemenata, tako da indeksi idu u opsegu od 0 do 4. Međutim, petlja ide
od 0 do 5. Kao posljedica, u posljednjem ciklusu for petlje izvršit će se sljedeća sekvenca kôda:
if (niz[5] > maxValue)
maxValue = niz[5];
ali član niz [5] našeg niza nije definisan! Ovo može da izazove raličite probleme, a
najvjerovatnije je da će niz [5] imati neku nedodijeljenu vrijednost ili beskonačno veliki broj.
Kao posljedica greške u pisanju kôda promjenljivoj maxValue će biti dodijeljena pogrešna
vrijednost.
Ono što je još veći problem kod izlaska iz opsega je dodjela vrijednosti članu niz[5], što može
dovesti do izmjene neke druge promjenljive (ili dijela promjenljive). Ovakve greške u
programu su jedne od težih za otkrivanje a mogu da izazovu ozbiljne probleme!
Prosljeđivanje niza funkciji
Da bi se niz proslijedio funkciji kroz listu argumenata, postoje tri načina na koja se to može
uraditi. Sva tri načina su veoma slična međusobno, i proizvode isti rezultat, zato što svi
slučajevi šalju poruku kompajleru da se radi sa pokazivačem na cjelobrojnu vrijednost. Na
sličan način je moguće proslijediti i višedimenzionalne nizove što će biti pokazano u
nastavku. Postoje tri načina da se niz kroz listu argumenata proslijedi funkciji: kao pokazivač,
kao dimenzionisani niz i kao nedimenzionisani niz.
• Prosljeđivanje niza korištenjem pokazivača kao formalnog parametra:
void myFunction(int *param)
{
...
}
• Formalni parametar kao dimenzionisani niz, kao što je dato u nastavku:
void myFunction(int param[10])
{
...
}
• Formalni parametar kao nedimenzionisani niz:
void myFunction(int param[])
{
...
}

Primjer korištenja nizova u funkciji


Kada se ime niza proslijedi funkciji kroz listu argumenata prosljeđivanje se vrši po adresi.
Donji primjer koristi funkciju getProsjek() koja kao argumente uzima nedimenzionisani niz
arr i veličinu niza size, a kao rezultat vraća srednju vrijednost članova niza:
#include<iostream>
using namespace std;
double getProsjek(int arr[], int size)
{
int i; double avg, sum = 0;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = sum / size;
return avg;
}
int main()
{
const int N = 5;
/* cjelobrojni niz sa 5 elemenata */
int ocjene[N] = { 10, 6, 8, 7, 8 };
double avg;
/* proljeđuje pointer na niz kao argument */
avg = getProsjek(ocjene, N);
/* prikaz izlazne vrijednosti*/
cout << "Prosjecna vrijednost:" << avg << endl;
return 0;
}

Kao što se vidi iz prethodnog primjera, nije neophodno navesti dimenziju niza u listi
formalnih parametara jer C/C++ ne provjerava granice formalnih parametara (isto je kod C#
i Java).
Problem pretraživanja
Polje kao skup podataka istog tipa može biti efikasna struktura podataka za sortiranje ili
pretraživanje brojeva.
Npr., neka imamo:
Ulaz: Niz od n brojeva A = {a1, a2, . . . , an} i vrijednost x
Izlaz: Indeks i takav da x = A[i] ili specijalna vrijednost NIL ukoliko x nije u A.
U pseudo jeziku predstavit ćemo algoritam koji dati broj x nalazi u zadanom polju u O(n)
vremenu. Definirat ćemo funkciju koja će nam vratiti indeks lokacije u kojoj je nađeno x.
Ukoliko x nije u polju vratit će se prazan indeks. Koristit ćemo algoritam sekvencijalnog
pretraživanja.
seqPretrazi(A, x)
1 for i  1 to length(n)
2 do if x = A[i]
3 then return i
4 return NIL
Uočavamo da vrijeme izvršenja algoritma zavisi od broja iteracija for petlje što nam daje O(n)
vremensku složenost. Korektnost algoritma je jasna: prolazimo kroz sve elemente polja,
ukoliko takav broj nađemo, vraćamo indeks tog mjesta. Ako ne nađemo, sa return NIL
vraćamo prazan indeks. U pseudokodu je indeks prvog elementa označen brojem 1.
Konkretan programski kôd za slučaj pronalaska zajedničkih elemenata u dva 1D polja uz
pomoć algoritma sekvencijalnog pretraživanja izgleda:

#include <iostream>
#include <string>
using namespace std;
int seqPretrazivanje(const int x[], int size, int key)
{
for (int i = 0; i < size; i++)
if (key == x[i]) return i;
return -1;
}
void presjek(const int set1[], int size1,
const int set2[], int size2, int s[], int &size)
{
size = 0;
for (int i = 0; i < size1; i++)
if (seqPretrazivanje(set2, size2, set1[i]) > -1)
s[size++] = set1[i];
}
void display(const int x[], int size)
{
for (int i = 0; i < size; i++)
cout << x[i] << endl;
}
void main()
{
int x[] = { 1,2,3,4 };
int y[] = { 10,2,30,4,50 };
int size = 5;
int p[5];
presjek(x, 4, y, 5, p, size);
cout << "Zajednicki elementi su:" << endl;
display(p, size);
}

Izlaz:
4/10/2018

ALGORITMI I STRUKTURE PODATAKA

Sadržaj predmeta:
• Uvod u algoritme, analize algoritama
ALGORITMI I STRUKTURE PODATAKA • Složenost i ocjena složenosti algoritama, notacije
• Definicija i implementacija i aplikacija složenih struktura
podatka kao što su:
• Nizovi: jednodimenzionalni i višedimenzionalni nizovi
• Liste: jednostruko povezane, dvostruko povezane,
ć prstenovi i specijalni slučajevi kao što su stekovi i
redovi.
• Stabla: binarna, uravnotežena, stabla za traženje.
• Heap, hash tabele, grafovi.

1 2

ALGORITMI I STRUKTURE PODATAKA ALGORITMI I STRUKTURE PODATAKA


Elementi od kojih se grade strukture podataka
Elementi od kojih se grade strukture podataka
 Ćelija . . . varijabla koju promatramo kao  Zapis . . . (slog, structure u C++-u).
zasebnu cjelinu. Svaka ćelija ima svoj tip i adresu. Mehanizam udruživanja manjih dijelova strukture u
 Polje . . . (array u C++-u). veće.

Mehanizam udruživanja manjih dijelova Zapis čini više ćelija, koje ne moraju biti istog tipa, ali
strukture u veće. su pohranjene na uzastopnim adresama.
Polje čini više ćelija istog tipa pohranjenih na Broj, redosljed i tip ćelija je unaprijed zadan i
uzastopnim adresama. nepromjenljiv.
Broj ćelija je unaprijed zadan i nepromjenljiv. Pojedina ćelija se zove komponenta zapisa.
Jedna ćelija se zove element polja i Polja i zapisi se mogu kombinirati. (Npr, možemo imati
jednoznačno je određena pripadnom vrijednošću polje zapisa, zapis čije pojedine komponente su polja, polje
indeksa.
od polja, zapis čija komponenta je zapis, i slično.)

ALGORITMI I STRUKTURE PODATAKA ALGORITMI I STRUKTURE PODATAKA

Elementi od kojih se grade strukture podataka Elementi od kojih se grade strukture podataka
 Pointer . . . služi za uspostavljanje veze izmedu  Struktura - manje cjeline se udružuju u veće i
dijelova strukture. međusobno povezuju vezama.
 Pointer ili pokazivač je ćelija koja pokazuje neku  Dijagram pokazuje primjer strukture podataka koja se
drugu ćeliju. sastoji od niza zapisa povezanih pomoću pointera, te od
 Sadržaj pointera je adresa ćelije koju treba jednog polja zapisa. Zapisi su još međusobno povezani
pokazati. kursorima.
 Kursor . . . također služi za uspostavljanje veze
izmedu dijelova strukture.
 Kursor je ćelija tipa int koja pokazuje na element
nekog polja.
 Sadržaj kursora je indeks elementa kojeg treba
pokazati.

1
4/10/2018

ALGORITMI I STRUKTURE PODATAKA ALGORITMI I STRUKTURE PODATAKA

Strukture podataka Složene strukture podataka


Polja
jednodimenzionalna (nizovi, vektori)
dvodimenzionalna (matrice)
višedimenzionalna (tenzori višeg reda)

Povezane liste
Stekovi
Redovi

ALGORITMI I STRUKTURE PODATAKA


Problem pretraživanja
Niz
ZADANO: Niz V od N elemenata
Podatak x
Osnovna svojstva: TRAŽI SE: Je li xV, ako jeste na kojem je mjestu u nizu
- ima konačan broj elemenata N
- svi elementi istog tipa Algoritam SEKVENCIJALNO PRETRAŽIVANJE.
- elementi slijede jedan iza drugog
- direktan pristup svakom elementu O (1) Za svaki i=1 do N činiti

}
V1 Ako je Vi=x onda
V2 Ispiši “DA, na “,i,”. mjestu”
Završi algoritam
Vi Niz V ima N elemenata Ispiši “NE”

VN
Vremenska složenost algoritma: O(N) - “linearna složenost”

Problem pretraživanja Modifikacija problema pretraživanja


ZADANO: Niz V od N elemenata (1/2)
Podatak x
TRAŽI SE: Je li xV, ako jeste na kojem je mjestu u nizu ZADANO: Sortirani niz V od N elemenata (V1V2 ... VN)
Podatak x
Algoritam SEKVENCIJALNO PRETRAŽIVANJE (NIZ SORTIRAN) TRAŽI SE: Je li xV, ako jeste na kojem je mjestu u nizu

i=1
Dok god je Vi<=x činiti
Ako je Vi=x onda
dg=1 s=(dg+gg)/2 gg=N
Ispiši “DA, na “,i,”. mjestu”
Završi algoritam
i++
Ispiši “NE” - ako su podaci poredani (sortirani) onda
ne moramo provjeravati sve podatke!
Vremenska složenost algoritma: O(N) - “linearna složenost”

2
4/10/2018

Modifikacija problema pretraživanja Problem sortiranja (1/2)


(2/2) ZADANO: Niz V od N elemenata
TRAŽI SE: Preurediti elemente niza tako da bude
Algoritam BINARNO PRETRAŽIVANJE V1V2 ... VN
Postaviti dg=1, gg=N
Ponavljati
Postaviti s=(dg+gg)/2 Algoritam SELEKT SORT
Ako je Vs = x onda
Vremenska složenost
Ispiši “DA, na”,s,”. mjestu”
Završi algoritam
algoritma: Za svaki i=1 do N-1 činiti
O(log N) Za svaki j=i+1 do N činiti
Ako je x>Vs onda dg=s+1 “logaritamska složenost” Ako je Vi>Vj onda
Ako je x<Vs onda gg=s1
Ako je dggg onda Pozovi proceduru Zamjeni( Vi, Vj )
Ispiši “NE”
Završi algoritam

Problem sortiranja (2/2)


Kako deklarisati polje u C++
Vremenska složenost algoritma SELEKT SORT
O(N 2) - “kvadratna složenost” • Za deklaraciju polja u C++, treba navesti:
– tip podataka koji će se spremiti u polje
Algoritam procedure Zamjeni(x,y) – ime polja
temp = x – dimenziju polja:
x=y • jednodimenzionalno (lista vrijednosti),
y = temp • dvodimenzionalno (matrica ili tabela), itd.
– veličinu polja
• Primjeri
Vremenska složenost procedure Zamjeni je O(1) - izvršava se
“trenutačno”
– int x[10];
– float rezultati[30];
– int studentRezultati[30][5]; // dvodimenzionalno
polje za spremanje rezultata iz 5 zadataka za 30
studenata

Česta greška:
Jednodimenzionalno polje - niz
• Koristimo jednodimenzionalne (1D) nizove da na
Out-of-bound Run-time Error
jednostavan način sačuvamo i pristupimo spisku • Svi C ++ jednodimenzionalni nizovi sa N
vrijednosti podataka tako što ćemo ovim
vrijednostima dati zajedničko ime, npr
elemenata počinju sa indeksom 0 i završavaju
int x[4]; // sve vrijednosti su nazvane x se indeksom N-1.
10 x[0] const int N=5;
x[0] = 10; // vrijednost 1.člana je 10
x[1] = 5; // vrijednost 2. člana je 5 5 x[1] int v[N]; // sadrži 5 elemenata
x[2] = 20; // vrijednost 3. člana je 20 • Česta je greška u pokušaju pristupa N-tom
20 x[2]
x[3] = 30; // vrijednost 4. člana je 30
30 x[3]
elementu, npr. v [5] ili V [N], pošto je indeks
posljednjeg unosa niza N-1, a ne N.

3
4/10/2018

Inicijalizacija jednodimenzionalnih nizova Skladištenje vrijednosti u 1D nizovima


Postoje dva načina inicijalizacije jednodimenzionalnih nizova:
• Korištenjem petlje, npr. • Netačno:
int x[10];
for( int index=0; index<10; index++)
Int x[10];
x [index] = index+1 ; cin >> x;
▪ Navođenjem liste vrijednosti dok deklarišemo 1D niz, npr. ▪ Tačno:
int x[10] = {1,2,3,4,5,6,7,8,9,10};
int y[ ] = {0,0,0}; // ovaj niz sadrži 3 člana sa vrijednosti 0 int x[10];
double z[100] = {0}; // ovaj niz sadrži 100 ulaza, svi inicijalizirani sa 0 // Učitavanje jedne po jedne vrijednosti :
double w[20] = {5,3,1}; // ovaj niz sadrži 20 ulaza,
// prva tri ulaza su inicijalizirana sa 5, 3 i 1 for (int index=0; index<10; index++)
//respektivno a preostalih 17 se automatski inicijalizira sa 0
bool polozeni[10] = {true, true}; // ovaj niz sadrži 100 ulaza,
cin >> x[index];
// Prva dva su inicijalizirana sa true, a preostalih 8
// ulaza je automatski inicijalizirano sa false

Primjer: Učitavanje vrijednosti i prikaz u


Prikazivanje vrijednosti zapisanih u 1D nizovima
obrnutom redoslijedu
• Netačno :
Int x[10];
cout << x;

• Tačno:
int x[10];
// Prikazivanje jedne po jedne vrijednosti :
for (int index=0; index<10; index++)
cout << x[index] << endl;

Prosljeđivanje 1D nizova funkcijama Prosljeđivanje 1D nizova funkcijama


• Po defaultu nizovi se prosljeđuju funkcijama • Zašto ne koristimo sljedeći potpis da prenesemo
referencom, iako se ne piše referentni operator niz u funkciju?
(&) ispred imena niza. Zašto referencom? void process (int x[10]);
– Pošto nizovi čuvaju ogroman broj vrijednosti, mnogo • Nažalost, upotreba gornjeg potpisa znači da će
je brže i ekonomičnije da se prolazi nizom referencom
umjesto gubitka vremena i memorije kopiranjem ova određena funkcija obraditi samo 1D niz
vrijednosti nizova u druge nizove. veličine = 10 (ni više ni manje!)
• Primjer • Naravno, željeli bismo da napišemo funkciju koja
– Sljedeći potpis funkcije prihvata niz x kao referentni će raditi sa različitim veličinama nizova i zato
parametar i prihvata i broj elemenata u nizu (tj. umjesto toga koristimo sljedeći potpis
njegovu veličinu) void process (int x[ ], int size);
void process (int x[], int size);

4
4/10/2018

Prosljeđivanje 1D niza kao const referentnog


Primjer 2: Prosljeđivanje 1D niza funkciji
parametra
• Dobra ideja je proslijediti niz kao const
referentni parametar ako želimo osigurati da
funkcije neće promijeniti vrijednosti koje su
sačuvane u nizovima, npr.
void display (const int x[ ] , int size)
{
for (int i=0; i<size; i++)
cout << x[i] << endl;
}

Primjer: Traži najmanju vrijednost u nizu

int najmanji (const int x[ ], int n)


{
Manipulisanje s nizom //Pretpostavimo da x [0] sadrži najmanju vrijednost
int min = x[0];
for (int i=1; i<n; i++)
I. Pretraživanje… if (x[i]<min) min = x[i];
return min;
}

Primjer: Traži poziciju zadane vrijednosti u


Primjer: Daje index najmanje vrijednosti u nizu nesortiranom nizu korištenjem SEKVENCIJALNOG
PRETRAŽIVANJA
int min_index (int x[ ], int size, int start=0)
{
int index = start; Napominjemo da: int seqSearch (int x[ ], int size, int key)
int min = x[index]; 1. Niz nije sortiran! {
for (int i=index+1; i<size; i++) 2. Koristimo parametar start
if (x[i]<min) da odredimo indeks for (int i=0; i<size; i++)
{ početnog pretraživanja. 0
min = x[i];
if (x[i]== key) return i;
je podrazumijevana
index = i; vrijednost ovog parametra return -1; Funkcija vraća indeks prve
} 3. Kasnije ćemo koristiti ovu
return index; } vrijednosti koja je jednaka ključu
funkciju da sortiramo niz
} ako postoji, inače, vraća -1

5
4/10/2018

Primjer: Traži poziciju zadane vrijednosti u sortiranom


nizu korištenjem BINARNOG PRETRAŽIVANJA
int bSearch (int x[ ],int n,int key)
{
int dg=0, gg=n-1; NB.
do 1. Niz x mora biti sortiran!
{
int sred = (dg+gg)/2;
2. Svaka iteracija petlje
eliminiše polovinu trenutne
Manipulacija nizovima
if (x[sred] == key) return sred; dužine niza što čini ovu
if (x[sred]>key) tehniku pretraživanja bržom
gg=sred-1;
else
od sekvencijalne pretrage
3. Prestali smo da pretražimo
II. Izračunavanja.…
dg=sred+1; kada se desi lijevo> desno i
} while (dg<=gg); u tom slučaju vraćamo -1 da
return -1; bi ukazali na to da nismo
} mogli pronaći ključ u nizu

Primjer: Izračunavanje sume vrijednosti koje se


čuvaju u nizu Primjer: izračunavanje srednje vrijednosti polja

int sum (const int x[ ], int n)


double mean (const int x[ ], int n)
{
{
int s = 0;
for (int i=0; i<n; i++) s+=x[i]; return (double) sum(x,n) / n;
return s; }
}

Primjer : Množenje polja sa konstantnom


Primjer : Određivanje ranga vrijednosti u nizu
vrijednošću

int range (const int x[ ], int n) void multiply( int x[ ], int n, const int value)
{ {
return max (x, n) – min (x, n); for (int i=0; i<n; i++) x[i] *= value;
} }

6
4/10/2018

Primjer : Proizvod dva polja Primjer: Sabiranje/Oduzimanje dva polja

void add (const int x[], const int y[], int z[], int n)
int dotProduct( int x[ ], int y[ ], int n) {
{ for (int i=0; i<n; i++) z[i] = x[i] + y[i];
int sum = 0; }
for (int i=0; i<n; i++)
sum += x[i] * y[i]; void subtract (const int x[], const int y[], int z[], int n)
{
return sum;
for (int i=0; i<n; i++) z[i] = x[i] - y[i];
}
}

Primjer : Izdvaja vrijednosti koje su u prvom a


Primjer: Zajednički elementi dva polja
nisu u drugom polju
void presjek (const int set1[], int size1, const int set2[],
int size2, int s[], int &size)
{ void razliciti (const int set1[], int size1, const int set2[], int size2,
int s[], int &size)
size=0; {
for(int i=0; i<size1; i++) size=0;
if (seqSearch(set2, size2, set1[i])>-1) for(int i=0; i<size1; i++)
s[size++] = set1[i]; if (seqSearch(set2, size2, set1[i]) == -1)
} set[size++] = set1[i];
}

Primjer : Unija elemenata dva niza Primjer primjene polja: Konverzija cijelog broja iz dekadnog u
binarni b.s.
void unija (const int set1[], int size1, const int set2[], int size2,
int s[], int &size)
{
size = size1;
for(int i=0; i<size; i++) s[i]=set1[i];
for(int i=0; i<size2; i++)
if (seqSearch(s, size, set2[i]) == -1)
s[size++] = set2[i];
}

7
4/10/2018

Primjer primjene polja: Traženje najveće vrijednosti u


1D polju Primjer: Traženje pozicije najveće vrijednosti u 1D polju

Primjer: Bubble Sort

Uzima indeks najveće vrijednosti sačuvane u


opsegu [0, n-i] i zamjenjuje tu vrijednost sa
vrijednosti x [n-i-1]

8
4/10/2018

ALGORITMI I STRUKTURE PODATAKA

Sadržaj predmeta:
• Uvod u algoritme, analize algoritama
ALGORITMI I STRUKTURE PODATAKA • Složenost i ocjena složenosti algoritama, notacije
• Definicija i implementacija i aplikacija složenih struktura
podatka kao što su:
• Nizovi: jednodimenzionalni i višedimenzionalni nizovi
• Liste: jednostruko povezane, dvostruko povezane,
ć prstenovi i specijalni slučajevi kao što su stekovi i
redovi.
• Stabla: binarna, uravnotežena, stabla za traženje.
• Heap, hash tabele, grafovi.

1 2

ALGORITMI I STRUKTURE PODATAKA


Pokazivači i jednodimenzionalni nizovi
Elementi od kojih se grade strukture podataka
 Pointer . . . služi za uspostavljanje veze izmedu
dijelova strukture. • Ime niza (polja) je, ustvari, adresa prvog člana niza. Ako ime niza
 Pointer ili pokazivač je ćelija koja pokazuje neku pridijelimo pokazivaču (tip podatka na koji pokazuje mora biti
drugu ćeliju. identičan tipu elemenata niza), on postaje dvojnik niza. Npr.
int a[5]={ 3, 4, 9, 12, 4}; // Deklaracija i incijalizacija niza od 5 cijelih brojeva
 Sadržaj pointera je adresa ćelije koju treba
pokazati. int *p; // Deklaracija pokazivaca na int
p = a; // Incijalizacija pokazivača. Ime niza je adresa prvog clana niza.
 Kursor . . . također služi za uspostavljanje veze // dakle pokazivač pokazuje na prvi član niza a
izmedu dijelova strukture.
//Isto što i
 Kursor je ćelija tipa int koja pokazuje na element
p = &a[0];
nekog polja.
 Sadržaj kursora je indeks elementa kojeg treba
pokazati.

Pokazivači na nizove Pokazivači i jednodimenzionalni niz


Primjer
• Pokazivaču p ćemo dodijeliti adresu prvog elementa niza ocjene: • Ako pristupamo podacima niza preko pokazivača
int *p; tada možemo indeksirati elemente putem indeksa ili
int ocjene[10]; im pristupati putem pokazivačke aritmetike.
p = ocjene; • Pokazivačka aritmetika podrazumijeva dodavanje
• U C/C++ je dozvoljeno koristiti ime niza kao pokazivač, i obrnuto. cijelog broja na vrijednosti pokazivača, čime
• Ispravno: dobijemo adresu i-tog elementa.
*(ocjene + 4) ↔ ocjene[4] • Njegovu vrijednost dobivamo dereferenciranjem
p[4] ↔ ocjene[4] nove vrijednosti pokazivača.
*(p+4) ↔ ocjene[4] • Npr. *(p+i) je isto što i p[i] odnosno a[i]
*p ↔ ocjene[0]
*(p+1), *(p+2) itd ↔ ocjene[1] , ocjene[2] , itd

1
4/10/2018

Pokazivačka aritmetika Pristup elementima niza putem


pokazivačke aritmetike
• Operacije uvećanja i umanjenja pokazivača na niz
POSLJEDICA: pokazivač se pomjeri na naredni odnosno
prethodni element niza. • Potrebno je deklarisati pokazivač odgovarajućeg
• U C/C++ moguće je koristiti binarne operatore + i - za tipa i dodijeliti mu vrijednost adrese nultog
obavljanje aritmetičkih operacija nad pokazivačima. elementa niza korištenjem operatora & za
• Npr., može se modifikovati pokazivač na način da pokazuje na nalaženje adrese.
objekat koji je nekoliko memorijskih lokacija udaljen od objekta na • Zatim korištenjem operatora dereferenciranja
koji pokazivač originalno pokazuje. (indirekcije) * i relativne pozicije ostalih elemenata
• Ovakve aritmetičke operacija sa pokazivačima su često niza od nultog elementa, pristupiti svakom
pogodne kada se radi sa nizovima. Pretpostavimo da imamo
elementu niza.
pokazivač na cjelobrojnu promjenljivu (tipa int) i niz cjelih
brojeva (tipa int):

Pristup elementima niza putem


pokazivačke aritmetike Složene strukture podataka
• Primjer: Polja
: jednodimenzionalna (nizovi, vektori)
int ocjene[5]={7,9,6,8,7};
dvodimenzionalna (matrice)
int * p;
p=ocjene; //isto što i p=&ocjene[0]; višedimenzionalna (tenzori višeg reda)
for (int i=0; i<5; i++)
{
Povezani popis
cout<<*(p+i)<<endl; Stekovi
cout<<p[i]<<endl;
cout<<ocjene[i]<<endl; Redovi
}
:

Matrica (1/2) Matrica (2/2)


 A1,1 A1, 2 A1,3  A1, N 
Pravougaona shema podataka, svojstva: A A2, 2 A2,3  A2, N 
 2,1 
- podaci su raspoređeni u M redova i N kolona  A3,1 A3, 2 A3,3  A3, N 
 
- svi elementi istog tipa       
- direktan pristup svakom elementu  AM ,1 AM , 2 AM ,3  AM , N 

Poseban slučaj: M = N kvadratna matrica


Matricu A označavamo preciznije AMN

2
4/10/2018

Problem množenje matrica (1/2) Problem množenje matrica (2/2)


Algoritam MNOŽENJE MATRICA
ZADANO: Matrica A s m redova i n kolona
Za svaki i = 1 do m
Matrica B s n redova i k kolona
TRAŽI SE: Formirati matricu C = A•B, koja ima m redova i k Za svaki j = 1 do k
kolona
Ci,j = 0
Za svaki p = 1 do n
- svaki rezultat Ci,j jeste skalarni proizvod i-
tog reda matrice A i j-te kolone matrice B! Ci,j = Ci,j + Ai,p •B p,j

Vremenska složenost algoritma jeste O(m●n●k)

2D polja
Svaki element polja je određen brojem reda i kolone
u kojima se nalazi.

Obrada dvodimenzionalnih polja

Dvodimenzionalno polje može se obraditi na tri


različita načina:

• Obraditi čitavo polje

• Obraditi određeni red polja, tzv. obrada redova

• Obraditi određenu kolonu polja, tzv. obrada


kolona

3
4/10/2018

Obrada dvodimenzionalnih polja Dvodimenzionalna polja

• Svaki red i svaka kolona • Dvodimenzionalna polja se spremaju u


dvodimenzionalnog polja je određenom redoslijedu:
jednodimenzionalni niz – Prvi red se prvo zapiše, a zatim slijedi drugi red,
zatim treći red i tako dalje.
• Prilikom obrade određenog reda ili kolone • Kada deklarišemo dvodimenzionalno polje
dvodimenzionalnog polja: kao formalni parametar:
– možemo smanjiti veličinu prve dimenzije, ali ne
– Koristimo algoritme slične procesiranju i drugu
jednodimenzionalnih nizova
– broj kolona mora biti naveden.

Manipulisanje sa 2D poljem (matricom) Manipulisanje sa 2D poljem (matricom)

Manipulisanje sa 2D poljem (matricom)

4
4/10/2018

Inicijalizacija 2D polja u C++


#include <iostream> Primjer: Napisati funkciju pod nazivom donja_polovica ()
int main()
{ koja uzima dvodimenzionalni niz A, sa N redova i N kolona
int _2DArray[5][6] = { { 1, 2, 3, 4, 5, 6}, kao argumentom i prikazuje donju polovicu polja.
{ 7, 8, 9, 0, 1, 2},
{ 3, 4, 5} }; 2 3 1 5 0
for (int i = 0; i < 5; i++)
{ 7 1 5 3 1
for (int j = 0; j < 6; j++)
{ 2 5 7 8 1
cout << _2DArray [i][j]<< " ";
} 0 1 5 0 1 Rezultat:
cout << endl; Rezultat: 2
} 3 4 9 1 5
1 2 3 4 5 6 7 1
cout << endl; 7 8 9 0 1 2
2 5 7
return 0; 3 4 5 0 0 0
} 0 0 0 0 0 0 0 1 5 0
0 0 0 0 0 0 3 4 9 1 5

Pokazivači i višedimenzionalni nizovi


Primjer: Napisati funkciju koja uzima 2D niz integer-a i
njegovu veličinu kao argumente i prikazuje elemente
koji leže na dijagonalama. • Nizove elemenata možemo napraviti od bilo kojeg tipa
const int n = 5; podataka.
void Diagonals( int A[n][n], int size) • Kako su pokazivači također tip podatka i od njih možemo
{ int i, j; napraviti niz i s njima raditi kao sa bilo kojim nizom drugih
cout << “Glavna dijagonala:”<<endl; tipova podataka. Npr.
for (i=0 ; i<n; i++) int *p[3];
cout << A[i][i]<< “ “; je deklaracija niza od 3 pokazivača koji pokazuju na int.
cout<< “Sporedna dijagonala:”<<endl; • Također takav niz možemo i incijalizirati prilikom
for (i = 0; i<n; i++) deklarisanja. Npr.
cout<<A[i][n-(i+1)]<< “ “; int *p[3]={p1, p2, p3};
}

Pokazivači i višedimenzionalni nizovi Pokazivači i stringovi C tipa


• String je niz znakova (karaktera). On nije poseban tip
podatka.
• Primjer : • String C tipa je niz znakova koji završava s kontrolnim
Napisati program koji će upotrebom niza pokazivača na znakom ‘ \0‘. Prilikom ispisa stringa taj znak ne vidimo.
jednodimenzionalne nizove cijelih brojeva (dužine 3 • Konstantan string C tipa je tekst navođen između
elementa) formirati 3x3 matricu cijelih brojeva.
navodnika. Npr. “Ovaj tekst je konstantan string“.
• Ideja:
• Promjenjiva kojoj možemo pridjeljivati stringove je
int a1[3]={1,2,3}; p1=a1; p2=a2; p3=a3;
int a2[3]={4,5,6}; int* p[3]={p1,p2,p3};
ustvari pokazivač na znakove.
int a3[3]={7,8,9}; • Sljedeći primjer demonstrira upotrebu pokazivača na
int* p1, *p2, *p3; znak kao promjenjivu od stringa.

5
4/10/2018

Pokazivači i stringovi C tipa


...
char rijec[4] = { 'D', 'A', 'N','\0' }; //C stil znakovnog niza(stringa)
cout << " Preko imena niza: " << rijec << endl;
char * p1= rijec;
cout << " Preko pokazivaca: " << p1 << endl;
cout << " Preko pokazivacke aritmetike: ";
for (int i = 0; i < 3; i++)
cout << *(p1 + i);
cout << endl;

char *p2 = "Microsoft";


cout << " Preko pokazivaca p2: " << p2 << endl;
...

6
AiSP (P) Primjeri sa nizovima _ AISP predavanje 3 i 4

PRIMJER PRISTUPA ELEMENTIMA NIZA


#include<iostream>
#include <cstdlib>
using namespace std;
void main()
{
const int N = 10;
int n[N]; /* n je niz od 10 cjelih brojeva */
int i, j;
for (i = 0; i < N; i++)
{
n[i] = i + 100; /* vrijednost elementa na poziciji i postavi na i + 100 */
}
/* ispis vrijednosti svakog elementa niza */
for (j = 0; j < 10; j++)
{
printf("Element[%d] = %d\n", j, n[j]);
}
}

PRIMJER KORIŠTENJA NIZOVA U FUNKCIJI


#include<iostream>
using namespace std;
double getProsjek(int arr[], int size)
{
int i; double avg, sum = 0;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = sum / size;
return avg;
}
int main()
{
const int N = 5;
/* cjelobrojni niz sa 5 elemenata */
int ocjene[N] = { 10, 6, 8, 7, 8 };
double avg;
/* proslijedi pointer na niz kao argument */
avg = getProsjek(ocjene, N);
/* prikaz izlazne vrijednosti*/
cout << "Prosjecna vrijednost:" << avg << endl;
return 0;
}
1
Primjer: Naći zajedničke elemente u 2 niza uz pomoć sekvencijalnog pretraživanja.
#include <iostream>
#include <string>
using namespace std;
int seqPretrazivanje(const int x[], int size, int key)
{
for (int i = 0; i < size; i++)
if (key == x[i]) return i;
return -1;
}
void presjek(const int set1[], int size1,
const int set2[], int size2, int s[], int &size)
{
size = 0;
for (int i = 0; i < size1; i++)
if (seqPretrazivanje(set2, size2, set1[i]) > -1)
s[size++] = set1[i];
}
void display(const int x[], int size)
{
for (int i = 0; i < size; i++)
cout << x[i] << endl;
}
void main()
{
int x[] = { 1,2,3,4 };
int y[] = { 10,2,30,4,50 };
int size = 0;
int p[4];
presjek(x, 4, y, 5, p, size);
cout << "Zajednicki elementi su:" << endl;
display(p, size);
}

Rez:

Primjer: Naći zajedničke elemente u 2 niza uz pomoć binarnog pretraživanja.


int x[] = { 10,12,14,16 };
int y[] = { 10,11,12,13,14};

#include <iostream>
#include <string>
using namespace std;

int binSearch(const int x[], int n, int key)


2
{
int left = 0, right = n - 1;
do
{
int mid = (left + right) / 2;
if (x[mid] == key) return mid;
if (x[mid]<key)
left = mid+1;
else
right = mid - 1;
} while (left <= right);
return -1;
}
void presjek(const int set1[], int size1,
const int set2[], int size2, int s[], int &size)
{
size = 0;
for (int i = 0; i < size1; i++)
if (binSearch(set2, size2, set1[i]) > -1)
s[size++] = set1[i];
}
void display(const int x[], int size)
{
for (int i = 0; i < size; i++)
cout << x[i] << endl;
}
void main()
{
int x[] = { 10,12,14,16 }; //Elementi ne moraju biti sortirani!!
int y[] = { 10,11,12,13,14}; //Elementi moraju biti sortirani!!
int size = 4;
int p[4];
presjek(x, 4, y, 5, p, size);
cout << "Zajednicki elementi su:" << endl;
display(p, size);
}

Rez:

Primjer: Različiti elementi u dva niza


#include <iostream>
#include <string>
using namespace std;
int seqPretrazivanje(const int x[], int size, int key)
{

3
for (int i = 0; i < size; i++)
if (key == x[i]) return i;
return -1;
}
void razlika(const int set1[], int size1,
const int set2[], int size2, int s[], int &size)
{
size = 0;
for (int i = 0; i < size1; i++)
if (seqPretrazivanje(set2, size2, set1[i]) == -1)
s[size++] = set1[i];
}

void display(const int x[], int size)


{
for (int i = 0; i < size; i++)
cout << x[i] << endl;
}
void main()
{
int x[] = { 1,2,3,4 };
int y[] = { 10,2,30,4,50 };
int size1 = 9, size2 = 9;
int r1[9];
int r2[9];
razlika(x, 4, y, 5, r1, size1);
razlika(y, 5, x, 4, r2, size2);
cout << "Razliciti elementi su:" << endl;
display(r1, size1);
display(r2, size2);
}

Rez:

Primjer: Unija elemenata dva niza


#include <iostream>
#include <string>
using namespace std;
int seqPretrazivanje(const int x[], int size, int key)
{
for (int i = 0; i < size; i++)
if (key == x[i]) return i;
return -1;
}
4
void unija(const int set1[], int size1,
const int set2[], int size2, int s[], int &size)
{
size = size1;
for (int i = 0; i < size; i++) s[i] = set1[i];
for (int i = 0; i < size2; i++)
if (seqPretrazivanje(s, size, set2[i]) == -1)
s[size++] = set2[i];
}
void display(const int x[], int size)
{
for (int i = 0; i < size; i++)
cout << x[i] << endl;
}
void main()
{
int x[] = { 1,2,3,4 };
int y[] = { 10,2,30,4,50 };
int size = 9;
int u[9];
unija(x, 4, y, 5, u, size);
cout << "Elementi oba niza:" << endl;
display(u, size);
}
Rez:

Konverzija dekadnog u binarni broj


#include <iostream>
#include <string>
using namespace std;
void main()
{
short int binary[64] = { 0 };
int index, bits = 0;
unsigned int n;
cout << "Unesite neki cijeli broj: ";
cin >> n;
cout << "Binarni oblik broja: ";
if (n == 0)
cout << 0 << endl;
else
{
while (n > 0)
{
binary[bits] = n % 2;

5
n /= 2;
bits++;
}
for (index = bits - 1; index >= 0; index--)
cout << binary[index];
cout << endl;
}
}

Primjer: Najveći element u polju


#include <iostream>
#include <string>
using namespace std;
int najveci(const int x[], int size)
{
// Pretpostavimo da je najveća vrijednost pohranjena u x [0]
int max = x[0];
for (int i = 1; i < size; i++)
if (x[i]>max) max = x[i];
return max;
}
void main()
{
int niz[10] = { 4,1,6,3,-5,2,9,5,7,8 };
cout << "Najveca vrijednost u polju iznosi:" << najveci(niz, 10) << endl;
}

Rez:

Primjer : Daje index od najvece vrijednosti


#include <iostream>
#include <string>
using namespace std;
int indexOdNajveceVrijednosti(const int x[], int size)
{
// Pretpostavimo da je najveća vrijednost x[0]
int max = x[0];
int index = 0;
for (int i = 1; i<size; i++)
if (max < x[i])
{
max = x[i];
index = i;
}
return index;
}
void main()
{
6
int niz[10] = { 4,1,6,3,-5,2,9,5,7,8 };
cout << "Najveca vrijednost u polju nalazi se na " << indexOdNajveceVrijednosti(niz,
10)+1<<".poziciji." << endl;
}
Rez:

Primjer: Insertion Sort


#include <iostream>
#include <string>
using namespace std;
int indexOdNajveceVrijednosti(const int x[], int size)
{
// Pretpostavimo da je najveća vrijednost x[0]
int max = x[0];
int index = 0;
for (int i = 1; i < size; i++)
if (max < x[i])
{
max = x[i];
index = i;
}
return index;
}
void zamijeni(int &x, int &y)
{
int pom = x;
x = y;
y = pom;
}
void insertionSort(int x[], int n)
{
for (int i = 0; i < n; i++)
zamijeni(x[indexOdNajveceVrijednosti(x, n - i)], x[n - i - 1]);
}

void display(string p, int x[], int size)


{
cout << p;
for (int i = 0; i < size; i++)
cout << x[i] << " ";
cout << endl;
}
void main()
{
int array[10] = { 4,1,3,2,7,6,10,9,5,8 };
display("Nesortirano polje:", array, 10);

7
insertionSort(array, 10);
display("Sortirano polje: ", array, 10);
}

8
PRIMJERI SA 5.PREDAVANJA IZ AiSP (MATRICE)

1.

#include<iostream>
using namespace std;
int main()
{
const int rows = 4;
const int cols = 3;
int mat[rows][cols];
int i, j;
//inicijalizacija
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
mat[i][j] = 0;
//ispis
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
cout << mat[i][j] << "\t";
cout << endl;
}
//unos elemenata
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
cin >> mat[i][j];
//ispis
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
cout << mat[i][j] << "\t";
cout << endl;
}
//suma svakog reda
for (i = 0; i < rows; i++)
{
int sum = 0;
for (j = 0; j < cols; j++)
sum += mat[i][j];
cout << "Suma " << i + 1 << ". reda je " << sum << endl;
}
//suma svake kolone
for (j = 0; j < cols; j++)
{
int sum = 0;
for (i = 0; i < rows; i++)
sum += mat[i][j];
cout << "Suma " << j + 1 << ". kolone je " << sum << endl;
}

1
//najveći element reda
for (i = 0; i < rows; i++)
{
int max = mat[i][0];
for (j = 0; j < cols; j++)
if (mat[i][j] > max)
max = mat[i][j];
cout << "Najveci el u " << i + 1 << ". redu je " << max << endl;
}
//najveći element kolone
for (j = 0; j < cols; j++)
{
int max = mat[0][j];
for (i = 0; i < rows; i++)
if (mat[i][j] > max)
max = mat[i][j];
cout << "Najveci el u " << j + 1 << ". koloni je " << max << endl;
}
}
Gornji primjer sa fjama
#include<iostream>
using namespace std;
const int rows = 4;
const int cols = 3;
void InitMat(int mat[][cols], int rows, int cols)
{
//inicijalizacija
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = 0;
}
//ispis
void IspisMat(int mat[][cols], int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
cout << mat[i][j] << "\t";
cout << endl;
}
}
//unos elemenata
void UnosMat(int mat[][cols], int rows, int cols)
{
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
cin >> mat[i][j];
}
//suma svakog reda
void SumaRedaMat(int mat[][cols], int rows, int cols)
{

2
for (int i = 0; i < rows; i++)
{
int sum = 0;
for (int j = 0; j < cols; j++)
sum += mat[i][j];
cout << "Suma " << i + 1 << ". reda je " << sum << endl;
}
}
//suma svake kolone
void SumaKolMat(int mat[][cols], int rows, int cols)
{
for (int j = 0; j < cols; j++)
{
int sum = 0;
for (int i = 0; i < rows; i++)
sum += mat[i][j];
cout << "Suma " << j + 1 << ". kolone je " << sum << endl;
}
}
//najveći element reda
void MaxElRedMat(int mat[][cols], int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
int max = mat[i][0];
for (int j = 0; j < cols; j++)
if (mat[i][j] > max)
max = mat[i][j];
cout << "Najveci el u " << i + 1 << ". redu je " << max << endl;
}
}
//najveći element kolone
void MaxElKolMat(int mat[][cols], int rows, int cols)
{
for (int j = 0; j < cols; j++)
{
int max = mat[0][j];
for (int i = 0; i < rows; i++)
if (mat[i][j] > max)
max = mat[i][j];
cout << "Najveci el u " << j + 1 << ". koloni je " << max << endl;
}
}

int main()
{
int mat[rows][cols];
int i, j;
//inicijalizacija
InitMat(mat, rows, cols);
//ispis
IspisMat(mat, rows, cols);
//unos elemenata
UnosMat(mat, rows, cols);
//ispis

3
IspisMat(mat, rows, cols);
//suma svakog reda
SumaRedaMat(mat, rows, cols);
//suma svake kolone
SumaKolMat(mat, rows, cols);
//najveći element reda
MaxElRedMat(mat, rows, cols);
//najveći element kolone
MaxElKolMat(mat, rows, cols);
}

2.

Primjer: Napisati funkciju pod nazivom donja_polovica () koja uzima dvodimenzionalni niz A, sa 5
redova i 5 kolona kao argumentom i prikazuje donju polovicu polja.
#include <iostream>
using namespace std;
int main()
{
int _2DArray[5][5] = {
{ 1, 2, 3,4,5 },
{ 6,7, 8, 9,10 },
{ 1, 1, 1,1,1 },
{ 2, 2, 2,2,2 },
{ 6,7,8,9,3 },
};
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
if (j > i)_2DArray[i][j] = 0;
}
cout << endl;
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
cout << _2DArray[i][j] << " ";
}
cout << endl;
}
cout << endl;
return 0;
}
3.
Primjer: Napisati funkciju koja uzima 2D niz integer-a i njegovu veličinu kao argumente i prikazuje elemente
koji leže na dijagonalama.

#include <iostream>
using namespace std;
const int n = 5;
void Dijagonale(int A[n][n], int size)
{

4
int i;
cout << "Glavna dijagonala : " << endl;
for (i = 0; i < n; i++)
cout << A[i][i] << " ";
cout << endl;
cout << "Sporedna dijagonala : " << endl;
for (i = 0; i < n; i++)
cout << A[i][n - (i + 1)] << " ";
cout << endl;
}
int main()
{
int _2DArray[5][5] = {
{ 1, 2, 3,4,5 },
{ 6,7, 8, 9,10 },
{ 1, 1, 1,1,1 },
{ 2, 2, 2,2,2 },
{ 6,7,8,9,3 },
};

Dijagonale(_2DArray, n);
return 0;
}

4.
Kreiranje matrice preko 1D niza pokazivača na 1D nizove
#include <iostream>
using namespace std;
const int n = 5;
int main()
{
int a1[3] = { 1,2,3 };
int a2[3] = { 4,5,6 };
int a3[3] = { 7,8,9 };
int* p1, *p2, *p3;
p1 = a1; p2 = a2; p3 = a3;
int* p[3] = { p1,p2,p3 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
cout << *(p[i] + j)<<"\t";
cout << endl;
}

return 0;
}

5
STRING
#include <iostream>
using namespace std;
const int n = 5;
int main()
{
char rijec[4] = { 'D', 'A', 'N','\0' }; //C stil znakovnog niza(stringa)
cout << "Preko imena niza: " << rijec << endl;
char * p1 = rijec;
cout << "Preko pokazivaca: " << p1 << endl;
cout << "Preko pokazivacke aritmetike: ";
for (int i = 0; i < 3; i++)
cout << *(p1 + i);
cout << endl;
char *p2 = "Microsoft";
cout << "Preko pokazivaca p2: " << p2 << endl;
return 0;
}

You might also like