1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne...

38
1 1. LINEARNE STRUKTURE PODATAKA 1.1. POLJE 1.1.1. DEFINICIJE I STRUKTURA Polje (array) predstavlja linearnu homogenu statičku strukturu podataka i sastoji se od fiksnog broja komponenata istog tipa. Svaki element polja se može označiti pomoću indeksa i svakom se elementu može direktno pristupati. Ukupan broj komponenti polja određen je pri njegovom opisu i ne može se menjati. Polje može biti jednodimenzionalno i višedimenzionalno. Adresa i-te komponente vektora A je data jednačinom: L0 +c*(i-1), gde su: L0 adresa prve reči prvog elementa vektora A, a c broj reči pridružen svakom elementu. Dvodimenzionalna polja se mogu memorisati po vrstama ili kolonama i mogu se prikazati ekvivalentnim jednodimenzionalnim vektorom. Adresa elementa A[i,j] dvodimenzionalnog polja smeštenog po kolonama data je izrazom: L0 +c*[(j-1)*n + (i-1)], gde je n broj vrsta. Analogno, adresa elementa A[i,j] dvodimenzionalnog polja smeštenog po vrstama data je izrazom: L0 +c*[(i-1)*n + (j-1)]. Analogno se smeštaju i višedimenzionalna polja u memoriju. 1. NCP koji sa standardnog ulaza učitava raspored 8 topova na šahovskoj tabli. Raspored se učitava u formi 8 linija sa po 8 brojeva po liniji. Ako na datom polju nema topa, učitava se 0, a inače 1. Program mora da ispita validnost unetog rasporeda ( da li su učitani brojevi ili 0 ili 1, da li ima 8 topova) i ispita da li se u datom rasporedu dva topa tuku. #include <stdio.h> #include <stdlib.h> main(){ int tabla[8][8]; /*matrica nula i jedinica cuva raspored 8 topova na tabli */ int suma; /* pamti se suma reda/kolone kao test osobina iz zahteva zadatka */ int i,j; /*brojaci u petljama */ /*ucitavanje podataka o rasporedu topova uz sumiranje broja topova i u slucaju greske stampa se odgovarajuca poruka i okoncava programa */ suma=0; for (i=0; i<8; i++ ) for (j=0; j<8; j++){ scanf("%d", &tabla[i][j]); /*test korektnosti ulaza */ if (tabla[i][j] !=0 && tabla[i][j] !=1 ){ printf ("\nNekorektni ulazni podaci o rasporedu topova\n"); exit(EXIT_FAILURE);

Transcript of 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne...

Page 1: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

1

1. 0BLINEARNE STRUKTURE PODATAKA

1.1. 1BPOLJE

1.1.1. 5BDEFINICIJE I STRUKTURA Polje (array) predstavlja linearnu homogenu statičku strukturu podataka i sastoji se od fiksnog broja

komponenata istog tipa. Svaki element polja se može označiti pomoću indeksa i svakom se elementu

može direktno pristupati. Ukupan broj komponenti polja određen je pri njegovom opisu i ne može se

menjati. Polje može biti jednodimenzionalno i višedimenzionalno.

Adresa i-te komponente vektora A je data jednačinom:

LR0R+c*(i-1),

gde su: LR0R – adresa prve reči prvog elementa vektora A, a c – broj reči pridružen svakom elementu.

Dvodimenzionalna polja se mogu memorisati po vrstama ili kolonama i mogu se prikazati

ekvivalentnim jednodimenzionalnim vektorom. Adresa elementa A[i,j] dvodimenzionalnog polja smeštenog

po kolonama data je izrazom:

LR0R+c*[(j-1)*n + (i-1)],

gde je n broj vrsta.

Analogno, adresa elementa A[i,j] dvodimenzionalnog polja smeštenog po vrstama data je izrazom:

LR0R+c*[(i-1)*n + (j-1)].

Analogno se smeštaju i višedimenzionalna polja u memoriju.

1. NCP koji sa standardnog ulaza učitava raspored 8 topova na šahovskoj tabli. Raspored se učitava u formi 8 linija sa po 8 brojeva po liniji. Ako na datom polju nema topa, učitava se 0, a inače 1. Program mora da ispita validnost unetog rasporeda ( da li su učitani brojevi ili 0 ili 1, da li ima 8 topova) i ispita da li se u datom rasporedu dva topa tuku.

#include <stdio.h> #include <stdlib.h> main(){ int tabla[8][8]; /*matrica nula i jedinica cuva raspored 8 topova na tabli */ int suma; /* pamti se suma reda/kolone kao test osobina iz zahteva zadatka */ int i,j; /*brojaci u petljama */ /*ucitavanje podataka o rasporedu topova uz sumiranje broja topova i u slucaju greske stampa se odgovarajuca poruka i okoncava programa */ suma=0; for (i=0; i<8; i++ ) for (j=0; j<8; j++){ scanf("%d", &tabla[i][j]); /*test korektnosti ulaza */ if (tabla[i][j] !=0 && tabla[i][j] !=1 ){ printf ("\nNekorektni ulazni podaci o rasporedu topova\n"); exit(EXIT_FAILURE);

Page 2: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

2

} suma=suma + tabla[i][j]; } /*greska je ako je broj topova na tabli razlicit od 8 */ if(suma !=8){ printf ("\nNekorektni ulazni podaci o broju topova\n"); exit(EXIT_FAILURE); } /*proveravanje da li se dva topa nalaze u istom redu , tj. da li je suma clanova nekog reda veca od 1 */ for(i=0;i<8;i++){ suma=0; for (j=0;j<8;j++) suma+=tabla[i][j]; if (suma >1 ) { printf ("\nTopovi se tuku\n"); exit(EXIT_SUCCESS); } } /*proveravanje da li se dva topa nalaze u istoj koloni , tj. da li je suma clanova neke kolone veca od 1 */ for(j=0;j<8;j++) { suma=0; for (i=0;i<8;i++) suma+=tabla[i][j]; if (suma >1 ) { printf ("\nTopovi se tuku\n"); exit(EXIT_SUCCESS); } } /*inace se topovi ne tuku */ printf ("\nTopovi se ne tuku\n"); exit(EXIT_SUCCESS); }

1.2. 2BSTEK

1.2.1. 6BDEFINICIJE I STUKTURA Stek (stack) ili magacin je jedna od najznačajnijih linearnih i dinamičkih struktura podataka. Stavljanje

(upis) ili brisanje (čitanje) elemenata se vrši samo na jednom kraju. Operacija stavljanja se naziva PUSH, a

brisanja POP. Stek se prazni i puni po tzv. LIFO strategiji.

#define MAXSTACKLEN 100 /* maksimalna dubina steka */ int stack[MAXSTACKLEN];/*vrednost steka */ int stackPointer;/*naredna slobodna pozicija na steku */ /* push: gurni na stek */ void push( int arg ){ if( stackPointer < MAXSTACKLEN ) stack[stackPointer++] = arg; else printf("greska: stek je pun, nemoguce je smestiti %g\n", arg); } /* pop: skini sa steka*/ int pop( void ){

Page 3: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

3

if( stackPointer > 0 ) return stack[--stackPointer]; else{ printf("greska: stek je prazan\n" ); return 0; } } int top(void){ if(stackPointer > 0) return stack[stackPointer-1]; else{ printf("greska: stek je prazan\n"); return 0; }

}

10BOpis zadatka: Za aritmetičke izraze kao što su T2+3T, T2+3*4T, T(2+3)*4T, itd. sa kojima se tipično susrećemo kako u

matematici tako i u programiranju, kažemo da su zapisani u Tinfiksnoj formiT, s obzirom da se operator

nalazi TizmeđuT operanada. Najveća mana ovakvog zapisa leži u činjenici da je neophodno uspostaviti

konvencije o TprioritetuT pojedinih operatora (npr. konvenciju da množenje ima veći prioritet u odnosu na

sabiranje), i eventualno koristiti zagrade za promenu prioriteta.

U računarstvu je od velikog značaja jedan posve drugačiji zapis aritmetičkih izraza, poznat pod

imenom TpostfiksnaT ili Tobrnuta poljska notacijaT, u kojem se operatori navode TnakonT operanada (naziv

obrnuta poljska notacija dat je u čast poljskog matematičara Jana Lukasiewitza, koji je predložio upravo

obrnuti princip - da se operatori zapisuju TispredT operanada). Na primer, prethodna tri izraza zapisana u

infiksnoj notaciji, u obrnutoj poljskoj notaciji zapisuju se ovako:

2 3 + 2 3 4 * + 2 3 + 4 *

Izračunavanje izraza u obrnutoj poljskoj notaciji izvodi se tako da se svaki operand na koji se naiđe dodaje na kraj liste (koja je na početku prazna), dok se prilikom nailaska na binarni operator poslednja dva elementa iz liste brišu i zamenjuju rezultatom operacije (sličan princip može se primeniti i na n-arne operatore). Broj koji na kraju izračunavanja ostane u listi predstavlja rezultat izračunavanja (taj broj mora biti jedinstven ako je izraz bio ispravan). Uzmimo na primer, sledeći izraz zapisan u obrnutoj poljskoj notaciji:

3 5 6 4 - * 6 + * 2 /

Izračunavanje ovog izraza teklo bi ovako:

3 3 5 3 5 6 3 5 6 4 3 5 2 T6 i 4 su zamijenjeni sa 6-4=2 3 10 T5 i 2 su zamijenjeni sa 5*2=10

Page 4: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

4

3 10 6 3 16 T10 i 6 su zamijenjeni sa 10+6=16 48 T3 i 16 su zamijenjeni sa 3*16=48 48 2 24 T48 i 2 su zamijenjeni sa 48/2=24

Dakle, rezultat izračunavanja je 24. Jedna od glavnih prednosti obrnute poljske notacije leži u činjenici

da nije potrebno voditi računa o prioritetu operacija, kao i da je Tsvaki T izraz moguće zapisati Tbez upotrebe zagradaT. Na primer, izraz koji bi se u infiksnom obliku zapisao kao

((3 + 5) / (7 - 2) + 4 / (8 - 5)) / (3 + 5 * (4 / (7 - 2)))

u obrnutoj poljskoj notaciji zapisuje se kao

3 5 + 7 2 - / 4 8 5 - / + 3 5 4 7 2 - / * + /

Stoga, kompajleri većine programskih jezika interno prevode sve aritmetičke izraze u obrnutu poljsku

notaciju pre bilo kakve dalje obrade. Vaš zadatak je da napravite program koji aritmetičke izraze u

infiksnom obliku koji se sastoje od jednoslovnih promjenljivih (a-z), četiri računske operacije (T+T, T-T, T*T i T/T), i

eventualno zagrada, pretvori u obrnutu poljsku notaciju.

11BUlazna datoteka: U prvom i jedinom redu ulazne tekstualne datoteke TRPN.INT nalazi se niz znakova koji predstavlja

aritmetički izraz u infiksnoj notaciji koji treba pretvoriti u postfiksnu odnosno obrnutu poljsku notaciju.

Ispravan aritmetički izraz sme sadržavati samo jednoslovne promenljive pisane malim slovima (od "a" do

"z"), binarne operatore " T+T", "T-T", "T*T" i "T/T" kao i male zagrade "(" i ")" za promenu prioriteta operacija.

Ispravan aritmetički izraz neće sadržati nikakve razmake.

12BIzlazna datoteka: Ukoliko ulazna datoteka sadrži ispravan aritmetički izraz u infiksnoj notaciji, tada u prvi i jedini red

izlazne tekstualne datoteke TRPN.OUTT treba upisati niz znakova koji predstavlja aritmetički izraz u obrnutoj

poljskoj notaciji. Ovaj izraz sastoji se od niza znakova koji smeju sadržavati samo mala slova (od "a" do

"z") i binarne operatore "T+T", "T-T", "T*T" i " T/T". Nikakvi razmaci u izrazu nisu dozvoljeni. Ukoliko ulazna datoteka

ne sadrži ispravan aritmetički izraz, u izlaznu datoteku treba samo ispisati tekst.

NEISPRAVAN IZRAZ

13BPrimeri: TRPN.IN x+y+z TRPN.OUT xy+z+ TRPN.IN x+(y+z) TRPN.OUT xyz++

TRPN.IN x+y*z TRPN.OUT xyz*+

TRPN.IN (x+y)*z TRPN.OUT xy+z* TRPN.IN x*(y+z TRPN.OUT NEISPRAVAN IZRAZ

Page 5: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

5

T

RPN.IN a+b/c+d TRPN.OUT abc/+d+ TRPN.IN (a+b)/(c+d) TRPN.OUT ab+cd+/ TRPN.IN x*(y+z*(a+b*(c-d))/e) TRPN.OUT xyzabcd-*+*e/+*

/****************************************** * IZRACUNAVANJE IZRAZA KOJI JE ZADAT U * * INVERZNOJ POLJSKOJ NOTACIJI * *******************************************/ int computePolish(char izraz[]){ char symbol; int sum,n,i; n=(int)strlen(izraz); i=0; while (i<n){ symbol=izraz[i]; if((symbol - '0')>=0 && (symbol - '0')<=9){ push(symbol-'0'); } if ( symbol == '+' || symbol == '-' || symbol == '*' || symbol == '/'){ int first, second; first = pop(); second = pop(); switch(symbol){ case '+': sum = first + second; break; case '-': sum = second - first; break; case '*': sum = second * first; break; case '/': sum = second / first; break; } push(sum); } i++; } return(top()); }

Page 6: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

6

/* PREVODJENJE IZRAZA IZ INFIKS U POSTFIKS FORMU */ #include <stdio.h> #include <stdlib.h> #include <io.h> #include <string.h> int Priority(char Operator) { if(Operator=='*'||Operator=='/') return 2; else if(Operator=='+'||Operator=='-') return 1; else return 0;} char *Compile(char *Expr) { static char *Error="NEISPRAVAN IZRAZ"; static char Comp[256]=""; char Last=0,Ch,Ch1,Stack[256]=""; int FindFlag,VarFlag=0,SSPtr=0,CompLen=0,SynError; int I,Parenths=0,Balance=0; for(I=0;I < (int)strlen(Expr);I++) { Ch=Expr[I]; SynError=1; if(Ch>='a' && Ch<='z' && !VarFlag) { VarFlag=1; SynError=0; Balance++; Comp[CompLen++]=Ch; } else VarFlag=0; if(Priority(Ch)) { if(Priority(Last)||Last=='(') return Error; while(1) { SynError=0; Ch1=Stack[SSPtr-1]; if(!SSPtr||Ch1=='('||Priority(Ch)>Priority(Ch1)) { Stack[SSPtr++]=Ch; break; } Comp[CompLen++]=Ch1; SSPtr--; Balance-=(Ch1=='+'||Ch1=='-'||Ch1=='*'||Ch1=='/'); } } if(Ch=='(') { Stack[SSPtr++]='('; SynError=0; Parenths++; } if(Ch==')'&&!(SynError=--Parenths<0)) while((Ch1=Stack[--SSPtr])!='(') { Comp[CompLen++]=Ch1; Balance-=(Ch1=='+'||Ch1=='-'||Ch1=='*'||Ch1=='/'); } if(SynError) return Error; Last=Ch; } if(Parenths||SynError) return Error; for(I=SSPtr-1;I>=0;I--) { Ch=Comp[CompLen++]=Stack[I]; Balance-=(Ch=='+'||Ch=='-'||Ch=='*'||Ch=='/'); } if(Balance!=1) return Error; Comp[CompLen]=0; return Comp; } int main(void) { char Str[256]; //ifstream InFile("RPN.IN"); ofstream OutFile("RPN.OUT"); //InFile>>Str; OutFile<<Compile(Str); FILE *f,*g; f=fopen("rpn.in","r"); g=fopen("rpn.out","w"); fscanf(f,"%s",Str); fprintf(g,"%s",Compile(Str)); fclose(f);fclose(g); return 0;}

Page 7: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

7

2. Rad sa stekom nepoznatok kapaciteta /* rad sa stekom unapred nepoznatog kapaciteta */ #include <stdio.h> #include <stdlib.h> typedef struct elem { int broj; struct elem *sled; } Elem; typedef Elem *Stek; Stek stvori (void); /* Stvaranje praznog steka. */ void stavi (Stek *stk, int b); /* Stavljanje broja na stek. */ int uzmi (Stek *stk); /* Uzimanje broja sa steka. */ int prazan (Stek stk); /* Da li je stek prazan? */ void pisi (Stek stk); /* Ispisivanje sadrzaja steka. */ void prazni (Stek *stk); /* Praznjenje steka. */ void unisti (Stek *stk); /* Unistavanje steka. */ int main () { Stek stk = stvori (); int b, izbor, kraj = 0; while (! kraj) { printf ("\n1. Smestaj podataka na stek\n" "2. Skidanje podatka sa steka\n" "3. Ispisivanje sadrzaja steka\n" "4. Praznjenje steka\n" "0. Zavrsetak rada\n\n" "Vas izbor? " ); scanf ("%d", &izbor); switch (izbor) { case 1: /* podatak na stek: */ printf ("Broj? "); scanf ("%d", &b); stavi (&stk, b); break; case 2: /* podatak sa steka: */ if (! prazan (stk)) printf ("Broj= %d\n", uzmi (&stk)); else printf ("*** Stek je prazan! ***\a\n"); break; case 3: /* Ispisivanje sadrzaja steka: */ printf ("Stek= "); pisi (stk); putchar ('\n'); break; case 4: /* Praznjenje steka: */ prazni (&stk); break; case 0: /* Zavrsetak rada: */ kraj = 1; break; default: /* Pogresan izbor: */ printf ("*** Neozvoljeni izbor! ***\a\n"); break; } } return 0; } Stek stvori () { return NULL; } /* Stvaranje praznog steka. */ void stavi (Stek *stk, int b) { /* Stavljanje broja na stek. */ Elem *novi = malloc (sizeof(Elem)); novi->broj = b; novi->sled = *stk; *stk = novi; } int uzmi (Stek *stk) { /* Uzimanje broja sa steka. */ Elem *stari; int b;

Page 8: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

8

if (*stk == NULL) exit (2); b = (*stk)->broj; stari = *stk; *stk = (*stk)->sled; free (stari); return b; } int prazan (Stek stk) { return stk == NULL; } /* Da li je stek prazan? */ void pisi (Stek stk) { Elem *tek; /* Ispisivanje sadrzaja steka. */ for (tek=stk; tek; tek=tek->sled) printf ("%d ", tek->broj); } void prazni (Stek *stk) { /* Praznjenje steka. */ while (*stk) { Elem *stari=*stk; (*stk)=(*stk)->sled; free(stari); } } void unisti (Stek *stk) { prazni (stk); } /* Unistavanje steka. */

7BPrimena steka – rekurzija Prilikom rekurzije moraju se poštovati dva osnovna principa:

1) Svaki sledeći poziv mora voditi ka konačnom rešenju problema

2) Mora postojati uslov za završetak procesa

#define DIM 1000 int faktorijelRekurzivno(int n){ int retv,pom; if(n==1) retv=1; else{ pom=faktorijelRekurzivno(n-1); retv=n*pom; } return retv; } int faktorijelNerekurzivno(int n){ int top=-1, stn[DIM],stretv[DIM],stadr[DIM],stpom[DIM]; int retv,adr,pom; step1: if(n==1){ retv=1; stretv[top]=retv; } else{ step2: //prevodjenje poziva faktorijelRekurzivno(n-1) top++; stn[top] = n; stretv[top] = retv; stpom[top] = pom; stadr[top] = 3; //postavi paramertre na nove vrednosti n--; goto step1; step3: pom = retv;

Page 9: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

9

retv = n*pom; stretv[top]=retv; } //prevodjenje return if(top == -1) return retv; else{ n = stn[top]; retv = stretv[top]; pom = stpom[top]; adr = stadr[top]; top--; if(adr == 3) goto step3; //posto je samo jedan rekurzivan poziv //jedno je i mesto odakle se posle pozivna nastavlja funkcija //goto step3 } } void move(int d, char f, char t) { /* move disk d from peg f to peg t */; printf("moving disk %d : %c --> %c\n", d, f, t); } void hanoi(int h, char f, char t, char r) { if (h > 0) { hanoi(h-1, f, r, t); move (h, f, t); hanoi(h-1, r, t, f); } } void hanoiNerekurzivno(int n, char poc, char pom, char kraj){ int stn[DIM], stpoc[DIM], stpom[DIM], stkraj[DIM], stadr[DIM]; int top=-1, adr, tmp; step1: if(n==1){ printf("\n %c -> %c ", poc, kraj); goto step5; } //prevodjenje poziva hanoi(n-1,poc,kraj,pom); top++; stn[top] = n; stpoc[top] = poc; stpom[top] = pom; stkraj[top] = kraj; stadr[top] = 3; //setuj parametre na nove vrednosti n--; poc = poc; tmp = pom; pom = kraj; kraj = tmp; goto step1; step3: printf("\n %c -> %c ", poc, kraj); //prevodjenje poziva hanoi(n-1,pom,poc,kraj)

Page 10: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

10

top++; stn[top] = n; stpoc[top] = poc; stpom[top] = pom; stkraj[top] = kraj; stadr[top] = 5; //setuj parametre na nove vrednosti n--; tmp = poc; poc = pom; pom = tmp; kraj = kraj; goto step1; step5: if(top == -1) return; else{ n = stn[top]; poc = stpoc[top]; pom = stpom[top]; kraj = stkraj[top]; adr = stadr[top]; top--; if(adr == 3) goto step3; if(adr == 5) goto step5; } }

2.1. 3BRED Kod steka se sva umetanja i brisanja izvršavaju na kraju koji se naziva vrh (TOP), dok se kod reda sva

umetanja izvršavaju na kraju – KRAJ, a sva brisanja na drugom kraju reda, tj. početku – Čelo.

Redovi su poznati kao FIFO memorije. Red S možemo implementirati kao konačan niz S[0..n-1] i pri

tome se koriste dva podatka, CELO i KRAJ da bi se oznčile granice reda. Ako je CELO < KRAJ tada se red

sastoji od S[CELO] ... S[KRAJ-1]. U suprotnom, ako je CELO > KRAJ, tada se red sastoji od

S[CELO],...,S[n-1],S[0],...,S[KRAJ-1], i ako je CELO = KRAJ, tada je red prazan.

Page 11: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

11

2.2. 4BLANČANE LISTE

2.2.1. 8B Definicija Lančana lista, za razliku od prethodnih struktura koristi lančani (spregnuti) način zauzeća memorije.

Prednosti korišćenja lančane liste:

- Količina rezervisane memorije ne mora biti unapred zadata i fiksirana. Tačan iznos zauzete

memorije će zavisiti isključivo od količine podataka koji se obrađuju.

- Moguće je brzo i često brisanje i umetanje podataka.

Elementi lančane liste nisu memorisani u uzastopnim memorijskim lokacijama, već svaki element

eksplicitno ukazuje na naredni element u memoriji. Postoji nekoliko tipova listi:

1) jednostruko spregnuta lista

2) dvostruko spregnuta lista

3) kružna lista

2.2.2. 9BJEDNOSTRUKO SPREGNUTA LINEARNA LISTA Svaki element ove strukture sadrži dva polja: podatak i pokazivač na naredni element u listi. Glava

liste je pokazivač koji sadrži adresu prvog elementa liste.

/* Rad sa jednostruko spregnutom listom - iterativne verzije funkcija za rad sa povezanom listom */ #include <stdio.h> #include <stdlib.h> typedef struct elem { int broj; struct elem *sled; } Elem; /*Element liste*/ int duz (Elem *lst); /* Broj elemenata liste. */ void pisi (Elem *lst); /* Ispisivanje liste. */ Elem *na_pocetak (Elem *lst, int b); /* Dodavanje na pocetak. */ Elem *na_kraj (Elem *lst, int b); /* Dodavanje na kraj. */ Elem *citaj1 (int n); /* Citanje liste stavljajuci brojeve na pocetak. */ Elem *citaj2 (int n); /* Citanje liste stavljajuci brojeve na kraj. */ Elem *umetni (Elem *lst, int b); /* Umetanje u uredjenu listu. */ void brisi (Elem *lst); /* Brisanje svih elemenata liste. */ Elem *izostavi (Elem *lst, int b); /* Izostavljanje svakog pojavljivanja. */ void main () { Elem *lst = NULL; int kraj = 0, izbor, broj, n; while (!kraj) { printf ("\n1. Dodavanje broja na pocetak liste\n" "2. Dodavanje broja na kraj liste\n" "3. Umetanje broja u uredjenu listu\n"

Page 12: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

12

"4. Izostavljanje broja iz liste\n" "5. Brisanje svih elemenata liste\n" "6. Citanje uz obrtanje redosleda brojeva\n" "7. Citanje uz cuvanje redosleda brojeva\n" "8. Odredjivanje duzine liste\n" "9. Ispisivanje liste\n" "0. Zavrsetak rada\n\n" "Vas izbor? " ); scanf ("%d", &izbor); switch (izbor) { case 1: case 2: case 3: case 4: printf ("Broj? "); scanf ("%d", &broj); switch (izbor) { case 1: /* Dodavanje broja na pocetak liste: */ lst = na_pocetak (lst, broj); break; case 2: /* Dodavanje broja na kraj liste: */ lst = na_kraj (lst, broj); break; case 3: /* Umetanje broja u uredjenu listu: */ lst = umetni (lst, broj); break; case 4: /* Izostavljanje broja iz liste: */ lst = izostavi (lst, broj); break; } break; case 5: /* Brisanje svih elemenata liste: */ brisi (lst); lst = NULL; break; case 6: case 7: /* Citanje liste: */ printf ("Duzina? "); scanf ("%d", &n); printf ("Elementi? "); brisi (lst); switch (izbor) { case 6: /* uz obrtanje redosleda brojeva: */ lst = citaj1 (n); break; case 7: /* uz cuvanje redosleda brojeva: */ lst = citaj2 (n); break; } break; case 8: /* Odredjivanje duzine liste: */ printf ("Duzina= %d\n", duz (lst)); break; case 9: /* Ispisivanje liste: */ printf ("Lista= "); pisi (lst); putchar ('\n'); break; case 0: /* Zavrsetak rada: */ kraj = 1; break; default: /* Pogresan izbor: */ printf ("*** Neozvoljeni izbor! ***\a\n"); break; } } } /* Definicije funkcija za obradu lista (iterativno). */ int duz (Elem *lst) { /* Broj elemenata liste. */ int n = 0; while (lst){ n++; lst = lst->sled; } return n; } void pisi (Elem *lst){ /* Ispisivanje liste. */ while(lst){ printf("%d ",lst->broj);

Page 13: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

13

lst = lst -> sled; } } Elem *na_pocetak(Elem *lst, int b){ /* Dodavanje na pocetak. */ Elem *novi = malloc(sizeof(Elem)); novi->broj = b; novi->sled = lst; return novi; } Elem *na_kraj (Elem *lst, int b) { /* Dodavanje na kraj. */ Elem *novi = malloc (sizeof(Elem)); novi->broj = b; novi->sled = NULL; if (!lst) return novi; else { Elem *tek = lst; while (tek->sled) tek = tek->sled; tek->sled = novi; return lst; } } Elem *citaj1 (int n) { /* Citanje liste stavljajuci brojeve na pocetak. */ Elem *prvi = NULL; int i; for (i=0; i<n; i++) { Elem *novi = malloc (sizeof(Elem)); scanf("%d", &novi->broj); novi->sled = prvi; prvi = novi; } return prvi; } Elem *citaj2 (int n) { /* Citanje liste stavljajuci brojeve na kraj. */ Elem *prvi = NULL, *posl = NULL; int i; for (i=0; i<n; i++) { Elem *novi = malloc (sizeof(Elem)); scanf ("%d", &novi->broj); novi->sled = NULL; if (!prvi) prvi = novi; else posl->sled = novi; posl = novi; } return prvi; } Elem *umetni (Elem *lst, int b) { /* Umetanje u uredjenu listu. */ Elem *tek = lst, *pret = NULL, *novi; while(tek && tek->broj < b){ pret = tek; tek = tek->sled; } novi = malloc (sizeof(Elem)); novi->broj = b; novi->sled = tek; if(!pret) lst = novi; else pret->sled = novi; return lst; } void brisi (Elem *lst) { /* Brisanje svih elemenata liste. */

Page 14: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

14

while(lst){ Elem *stari = lst; lst = lst->sled; free (stari); } } Elem *izostavi(Elem *lst, int b){ /* Izostavljanje svakog pojavljivanja. */ Elem *tek = lst, *pret = NULL; while(tek) if (tek->broj != b){ pret = tek; tek = tek->sled; } else { Elem *stari = tek; tek = tek->sled; if (!pret) lst = tek; else pret->sled = tek; free (stari); } return lst; }

/* Rad sa povezanom listom - REKURZIVNE verzije funkcija za rad sa povezanom listom; */ #include <stdio.h> #include <stdlib.h> typedef struct elem { int broj; struct elem *sled; } Elem; /*Element liste*/ int duz (Elem *lst); /* Broj elemenata liste. */ void pisi (Elem *lst); /* Ispisivanje liste. */ Elem *na_pocetak (Elem *lst, int b); /* Dodavanje na pocetak. */ Elem *na_kraj (Elem *lst, int b); /* Dodavanje na kraj. */ Elem *citaj1 (int n); /* Citanje liste stavljajuci brojeve na pocetak. */ Elem *citaj2 (int n); /* Citanje liste stavljajuci brojeve na kraj. */

Page 15: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

15

Elem *umetni (Elem *lst, int b); /* Umetanje u uredjenu listu. */ void brisi (Elem *lst); /* Brisanje svih elemenata liste. */ Elem *izostavi (Elem *lst, int b); /* Izostavljanje svakog pojavljivanja. */ void main () { Elem *lst = NULL; int kraj = 0, izbor, broj, n; while (!kraj) { printf ("\n1. Dodavanje broja na pocetak liste\n" "2. Dodavanje broja na kraj liste\n" "3. Umetanje broja u uredjenu listu\n" "4. Izostavljanje broja iz liste\n" "5. Brisanje svih elemenata liste\n" "6. Citanje uz obrtanje redosleda brojeva\n" "7. Citanje uz cuvanje redosleda brojeva\n" "8. Odredjivanje duzine liste\n" "9. Ispisivanje liste\n" "0. Zavrsetak rada\n\n" "Vas izbor? " ); scanf ("%d", &izbor); switch (izbor) { case 1: case 2: case 3: case 4: printf ("Broj? "); scanf ("%d", &broj); switch (izbor) { case 1: /* Dodavanje broja na pocetak liste: */ lst = na_pocetak (lst, broj); break; case 2: /* Dodavanje broja na kraj liste: */ lst = na_kraj (lst, broj); break; case 3: /* Umetanje broja u uredjenu listu: */ lst = umetni (lst, broj); break; case 4: /* Izostavljanje broja iz liste: */ lst = izostavi (lst, broj); break; } break; case 5: /* Brisanje svih elemenata liste: */ brisi (lst); lst = NULL; break; case 6: case 7: /* Citanje liste: */ printf ("Duzina? "); scanf ("%d", &n); printf ("Elementi? "); brisi (lst); switch (izbor) { case 6: /* uz obrtanje redosleda brojeva: */ lst = citaj1 (n); break; case 7: /* uz cuvanje redosleda brojeva: */ lst = citaj2 (n); break; } break; case 8: /* Odredjivanje duzine liste: */ printf ("Duzina= %d\n", duz (lst)); break; case 9: /* Ispisivanje liste: */ printf ("Lista= "); pisi (lst); putchar ('\n'); break; case 0: /* Zavrsetak rada: */ kraj = 1; break; default: /* Pogresan izbor: */ printf ("*** Neozvoljeni izbor! ***\a\n"); break; } } } /* Definicije funkcija za obradu lista (REKURZIVNO). */

Page 16: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

16

int duz (Elem *lst) { /* Broj elemenata liste. */ return lst ? duz (lst->sled) + 1 : 0; } void pisi (Elem *lst) { /* Ispisivanje liste. */ if (lst) { printf ("%d ", lst->broj); pisi (lst->sled); } } Elem *na_pocetak (Elem *lst, int b) { /* Dodavanje na pocetak. */ Elem *novi = malloc (sizeof(Elem)); novi->broj = b; novi->sled = lst; return novi; } Elem *na_kraj (Elem *lst, int b) { /* Dodavanje na kraj. */ if (!lst) { lst = malloc (sizeof(Elem)); lst->broj = b; lst->sled = NULL; } else lst->sled = na_kraj (lst->sled, b); return lst; } Elem *citaj1 (int n) { /* Citanje liste uz obrtanje redosleda. */ if (n == 0) return NULL; else { Elem *novi = malloc (sizeof(Elem)); novi->sled = citaj1 (n - 1); scanf ("%d", &novi->broj); return novi; } } Elem *citaj2 (int n) { /* Citanje liste uz cuvanje redosleda. */ if (n == 0) return NULL; else { Elem *novi = malloc (sizeof(Elem)); scanf ("%d", &novi->broj); novi->sled = citaj2 (n - 1); return novi; } } Elem *umetni (Elem *lst, int b) { /* Umetanje u uredjenu listu. */ if (!lst || lst->broj >= b) { Elem *novi = malloc (sizeof(Elem)); novi->broj = b; novi->sled = lst; return novi; } else { lst->sled = umetni (lst->sled, b); return lst; } } void brisi (Elem *lst) { /* Brisanje svih elemenata liste. */ if (lst) { brisi (lst->sled); free (lst); } } Elem *izostavi (Elem *lst, int b){ /* Izostavljanje svakog pojavljivanja. */ if (lst) { if (lst->broj != b) { lst->sled = izostavi (lst->sled, b);

Page 17: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

17

} else { Elem *stari = lst; lst = izostavi (lst->sled, b); free (stari); } } return lst; }

2.2.3. KRUŽNO SPREGNUTA LINEARNA LISTA Kod ovog tipa liste pokazivač poslednjeg elementa nema NULL vrednost već ukazuje na prvi element

liste. Prednosti ovog tipa liste su:

- Svakom elementu se može pristupiti polazeći od bilo kog elementa liste.

- Jednostavnije pronalaženje elemenata liste.

- Efikasnije operacije dodavanja i brisanja elemenata iz liste.

Kod ovog tipa liste neophodno je znati prvi ili poslednji element. To možemo rešiti na dva načina:

1) Pokazivač na glavu liste

2) Označavanje početnog elementa liste. Npr. ostaviti prazno polje za podatak, ili u njega upisati

specijalni simbol... itd.

2.2.4. DVOSTRUKO POVEZANA LINEARNA LISTA Kod ovog tipa listi, svaki element ima dva pokazivača koji ukazuju na prethodni i naredni element (levi

i desni ukazivač).

Levi ukazivač krajnjeg levog i desni pokazivač krajnjeg desnog elementa su NULL.

Page 18: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

18

2. NCP koji iz neprazne datoteke broj.txt ucitava paran broj celih brojeva x[1], x[2],...,x[n], gde n nije unapred poznato. Ispisati poruku na standardni izlaz da li vazi da x[1]==x[n], x[2]==x[n-1],..., x[k]=x[k+1], k=1..n/2

#include <stdio.h> #include <stdlib.h> typedef struct listacv dvlista; /*dvostruko povezana linearna lista*/ struct listacv{ int broj; /*informaciono polje je clan niza x*/ dvlista *sledeci, *prethodni; }; dvlista *ubaci(dvlista *kraj, int broj){ dvlista *novi; /*novi cvor za umetanje u listu*/ novi=(dvlista *)malloc(sizeof(dvlista)); /*alokacija memorije za novi cvor liste*/ novi->broj=broj; /*inicijalizacija polja broj u cvoru novi */

Page 19: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

19

novi->sledeci=NULL; novi->prethodni=kraj; /*novi element se dodaje na kraj postojece liste*/ kraj->sledeci=novi; /* do tada poslednji cvor kraj je ispred clana novi*/ kraj=novi; /*poslednji dodat element je novi kraj liste*/ return kraj; } main() { dvlista *prvi, *kraj; /*prvi i poslednji cvor dvostruke liste*/ int n; /*broj ucitanih celih brojeva*/ int broj; /*tekuci broj sa ulaza*/ int jednak; /*indikator jednakosti dva clana - cuva vrednost 0 ili 1 */ FILE *ulaz; int i; /*brojacka promenljiva*/ /*otvaranje datoteke za citanje i upis brojeva iz datoteke u dvostruku povezanu listu */ ulaz=fopen("broj.txt", "r"); fscanf(ulaz, "%d", &broj); /*kreiranje prvog cvora liste za prvi ucitan broj */ prvi=(dvlista*)malloc(sizeof(dvlista)); prvi->broj=broj; prvi->sledeci=NULL; prvi->prethodni=NULL; kraj=prvi; n=1; //za sada ucita je samo jedan clan /*formiranje liste od brojeva koji se ucitavaju sve do kraja datoteke - feof(ulaz) */ while (!feof(ulaz)) { fscanf(ulaz, "%d", &broj); kraj=ubaci (kraj, broj); n++; } fclose(ulaz); /*testiranje jednakih parova uz pomeranje tekuceg prvog clana i tekuceg poslednjeg clana ka sredini liste*/ jednak=1; for(i=1; i<=n/2 && jednak; i++) { jednak=jednak&&(prvi->broj==kraj->broj); prvi=prvi->sledeci; /*pomeranje ka sredini liste */ kraj=kraj->prethodni; /*pomeranje ka sredini liste */ } printf("Za unete broje jednakost "); if(!jednak) printf("ne "); printf("vazi\n"); return 0; }

2.2.5. PRIMENE SPREGNUTIH LINEARNIH LISTI

Prikaz polinoma Pretpostavimo da imamo polinom od tri promenljive: 3X2 + 4XY + Y2 + XYZ

Svaki element liste koji prikazuje jedan član polinoma dat je na sledećoj slici:

Page 20: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

20

Spregnuta lista za prikaz ovog polinoma izgledala bi:

Odgovarajuća struktura elementa bi bila:

typedef struct elem element; struct elem{

int expx; int expy; int expz; int koef; element *naredni; }

3. NCP-e za sabiranje, oduzimanje i množenje polinoma jedne promenljive. #include <stdio.h> #include <stdlib.h> #include <math.h> struct pnode{ double coef; long power; struct pnode *link; }; typedef struct pnode poly; #define COEF(a)((a)->coef) #define POWER(a)((a)->power) #define LINK(a)((a)->link) poly *addElem(poly *p, double coef, long pow){ poly *c,*newel,*pret=NULL; c = p; while(c && POWER(c) > pow){ pret=c; c = LINK(c); } if(!c || POWER(c) < pow){ newel = (poly*)malloc(sizeof(poly)); COEF(newel) = coef; POWER(newel) = pow; LINK(newel) = c; if(!pret) p = newel; else LINK(pret) = newel; return p; } if(POWER(c) == pow){ COEF(c) += coef; return p;

Page 21: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

21

} } poly *create(){ int pow; double c; poly *p=NULL; printf("\nUnesite polinom pocev od najveceg stepena:\n"); while(1){ printf("\nKoeficijent: "); scanf("%lf",&c); printf("\nStepen: "); scanf("%d",&pow); if(c == 0) break; p = addElem(p,c,pow); if(pow == 0) break; } return p; } void display(poly *p){ poly *cur=p; if(cur){ printf(" %c %.2f * X^%d",COEF(cur)<0?'-':' ',fabs(COEF(cur)),POWER(cur)); cur=LINK(cur); } while(cur != NULL){ printf(" %c %.2f * X^%d",COEF(cur)<0?'-':'+',fabs(COEF(cur)),POWER(cur)); cur=LINK(cur); } } poly *polyadd(poly* p1, poly* p2){ poly *p, *res=NULL; p=p1; while(p){ res=addElem(res,COEF(p),POWER(p)); p=LINK(p); } p=p2; while(p){ res=addElem(res,COEF(p),POWER(p)); p=LINK(p); } return res; } poly *polysub(poly* p1, poly* p2){ poly *p, *res=NULL; p=p1; while(p){ res=addElem(res,COEF(p),POWER(p)); p=LINK(p); } p=p2; while(p){ res=addElem(res,-COEF(p),POWER(p)); p=LINK(p); }

Page 22: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

22

return res; } poly *polymul(poly* p1, poly* p2){ poly *pom1,*pom2,*res=NULL; pom1=p1; while(pom1){ pom2=p2; while(pom2){ res=addElem(res,COEF(pom1)*COEF(pom2),POWER(pom1)+POWER(pom2)); pom2=LINK(pom2); } pom1=LINK(pom1); } return res; } poly *polydif(poly* p1){ poly *pom1,*res=NULL; pom1=p1; while(pom1){ if(POWER(pom1)!=0) res=addElem(res,COEF(pom1)*POWER(pom1),POWER(pom1)-1); pom1=LINK(pom1); } return res; } void brisi(poly *p){ poly *stari; while(p){ stari=p; p=LINK(p); free(stari); } } void main(){ int ch; poly *poly1,*poly2,*poly3; poly1=poly2=poly3=NULL; printf("\nUnesite prvi polinom:\n"); poly1=create(); display(poly1); poly2=create(); display(poly2); while(1){ printf("************************" "\nOdaberi operaciju:\n" "1.Sabiranje\n" "2.Oduzimanje\n" "3.Mnozenje\n" "4.Izvod\n" "5.Izlaz\n"); scanf("%d",&ch); switch(ch){ case 1: poly3=polyadd(poly1,poly2); break; case 2: poly3=polysyb(poly1,poly2);

Page 23: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

23

break; case 3: poly3=polymul(poly1,poly2); break; case 4: poly3=polydif(poly1); break; default: exit(1); } } brisi(poly1); brisi(poly2); brisi(poly3);

}

RETKO POSEDNUTE MATRICE Realizuje se preko spregnutih listi i ima za cilj smanjenje broja izračunavanja, kao i smanjenje

potrebne memorije za čuvanje sturkture.

Jedna moguća reprezentacija dvodimenzionalne retko posednute matrice bi bila preko jedne

spregnute liste za svaki red i svaku kolonu matrice. Svaka od ovih listi ima zaglavlje, tj. glavu. Svakom

nenultom mestu u matrici odgovara jedan čvor oblika:

struct cvor { int red; int kolona; int vrednost; struct cvor *nar_u_kol; struct cvor *nar_u_vrsti; }

/* Implementacija dinamickih kvadratnih matrica preko pokazivaca na niz pokazivaca na kolone */ #include <stdio.h>

Page 24: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

24

#include <stdlib.h> /* Tip elemenata matrice ce biti float */ typedef float tip; /* Funkcija alocira matricu dimenzije n*n */ tip** allocate(int n){ tip **m; int i; /* Alocira se niz pokazivaca na kolone */ m=(tip**)malloc(n*sizeof(tip*)); for (i=0; i<n; i++) /* Alociraju se nizovi brojeva koji predstavljaju kolone */ m[i]=(tip*)malloc(n*sizeof(tip)); return m; } /* Funkcija vrsi dealociranje date matrice dimenzije n */ void deallocate(tip** m, int n){ int i; /* Uklanjaju se kolone */ for (i=0; i<n; i++) free(m[i]); /* Uklanja se niz pokazivaca na kolone */ free(m); } /* Funkcija ispisuje datu matricu dimenzije n */ void IspisiMatricu(tip** matrica, int n){ int i,j; for (i=0; i<n; i++){ for(j=0; j<n; j++) printf("%f\t",matrica[i][j]); printf("\n"); } } /* Funkcija ucitava datu matricu i njenu dimenziju */ void UnesiMatricu(tip*** matrica,int *pn){ int i,j; printf("Unesite dimenziju kvadratne matrice :"); scanf("%d",pn); *matrica=allocate(*pn); for (i=0; i<*pn; i++) for(j=0; j<*pn; j++){ printf("A[%d][%d]=",i+1,j+1); scanf("%f",&((*matrica)[i][j])); } } /* Rekurzivna funkcija koja vrsi Laplasov razvoj - neefikasna, ali dobra vezba */ tip determinanta(tip** matrica, int n){ int i; tip** podmatrica; int det=0,znak; /* Izlaz iz rekurzije je matrica 1x1 */ if (n==1) return matrica[0][0]; /* Podmatrica ce da sadrzi minore polazne matrice */ podmatrica=allocate(n-1); znak=1; for (i=0; i<n; i++){ int vrsta,kolona; for (kolona=0; kolona<i; kolona++) for(vrsta=1; vrsta<n; vrsta++)

Page 25: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

25

podmatrica[vrsta-1][kolona]=matrica[vrsta][kolona]; for (kolona=i+1; kolona<n; kolona++) for(vrsta=1; vrsta<n; vrsta++) podmatrica[vrsta-1][kolona-1]=matrica[vrsta][kolona]; det+=znak*matrica[0][i]*determinanta(podmatrica,n-1); znak*=-1; } deallocate(podmatrica,n-1); return det; } main(){ /* Matrica i njena dimenizija */ tip **matrica; int n; /* Unosi se matrica */ UnesiMatricu(&matrica,&n); /* Ispisuje se determinanta */ printf("Determinanta je : %f\n",determinanta(matrica,n)); return 0;

}

1. NCP koji unosi sa standardnog ulaza dve realne matrice A, B i ispisuje na standardni izlaz A+B, A-B, A*B. Dimenzije matrica nisu unapred poznate. Ispisati poruke o greskama na standardni tok za poruke o gresci.

#include <stdio.h> #include <stdlib.h> typedef struct { float **a; int m, n; } Din_mat; /* Struktura matrice. */ Din_mat stvori (int m, int n); /* Dodela memorije. */ void unisti (Din_mat dm); /* Oslobadjanje memorije*/ Din_mat kopiraj (Din_mat dm); /* Kopiranje matrice. */ Din_mat citaj (int m, int n); /* Citanje matrice. */ void pisi (Din_mat dm, const char *frm, int max); /* Ispisivanje matrice. */ Din_mat transpon (Din_mat dm); /* Transponovana matrica*/ Din_mat zbir (Din_mat dm1, Din_mat dm2); /* Zbir matrica. */ Din_mat razlika (Din_mat dm1, Din_mat dm2); /* Razlika matrica. */ Din_mat proizvod (Din_mat dm1, Din_mat dm2); /* Proizvod matrica. */ typedef enum {MEM, DIM} Greska; /* Kodovi poruka o gresakama. */ const char *poruke[] = { "Neuspela dodela memorije", /* Poruke o gresci.*/ "Neusaglasene dimenzije matrica" }; int main () { while (1) { Din_mat dm1, dm2, dm3; int m, n; printf ("Broj vrsta, broj kolona: "); scanf ("%d%d", &m, &n); if (m<=0 || n<=0) break; printf ("Prva matrica: "); dm1 = citaj (m, n); printf ("Broj vrsta, broj kolona: "); scanf ("%d%d", &m, &n); if (m<=0 || n<=0) break; printf ("Druga matrica: "); dm2 = citaj (m, n); if (dm1.m==dm2.m && dm1.n==dm2.n) { dm3 = zbir (dm1, dm2); printf ("ZBIR:\n"); pisi (dm3, "%8.2f", 8);

Page 26: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

26

unisti (dm3); dm3 = razlika (dm1, dm2); printf ("RAZLIKA:\n"); pisi (dm3, "%8.2f", 8); unisti (dm3); } if (dm1.n == dm2.m) { dm3 = proizvod (dm1, dm2); printf ("PROIZVOD:\n"); pisi (dm3, "%8.2f", 8); unisti (dm3); } putchar ('\n'); unisti (dm1); unisti (dm2); } return 0; } static void greska (Greska g) { /* Ispisivanje poruke o gresci. */ fprintf (stderr, "\n*** %s! ***\n\a", poruke[g]); exit (g+1); } Din_mat stvori (int m, int n) { /* Dodela memorije. */ int i; Din_mat dm; dm.m = m; dm.n = n; if ((dm.a = malloc (m * sizeof(float*))) == NULL) greska (MEM); for (i=0; i<m; i++) if ((dm.a[i] = malloc (n * sizeof(float))) == NULL) greska (MEM); return dm; } void unisti (Din_mat dm) { /* Oslobadjanje memorije*/ int i; for (i=0; i<dm.m; free(dm.a[i++])); free (dm.a); } Din_mat kopiraj (Din_mat dm) { /* Kopiranje matrice. */ int i, j; Din_mat dm2 = stvori (dm.m, dm.n); for (i=0; i<dm.m; i++) for (j=0; j<dm.n; j++) dm2.a[i][j] = dm.a[i][j]; return dm2; } Din_mat citaj (int m, int n) { /* Citanje matrice. */ int i, j; Din_mat dm = stvori (m, n); for (i=0; i<m; i++) for (j=0; j<n; scanf("%f",&dm.a[i][j++])); return dm; } void pisi (Din_mat dm, const char *frm, int max){ /* Ispisivanje matrice. */ int i, j; for (i=0; i<dm.m; i++) { for (j=0; j<dm.n; j++) { printf (frm, dm.a[i][j]);

Page 27: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

27

putchar ((j%max==max-1 || j==dm.n-1) ? '\n' : ' '); } if (dm.n > max) putchar ('\n'); } } Din_mat transpon (Din_mat dm) { /* Transponovana matrica*/ int i, j; Din_mat dm2 = stvori (dm.n, dm.m); for (i=0; i<dm.m; i++) for (j=0; j<dm.n; j++) dm2.a[j][i] = dm.a[i][j]; return dm2; } Din_mat zbir (Din_mat dm1, Din_mat dm2) { /* Zbir matrica. */ int i, j; Din_mat dm3; if (dm1.m!=dm2.m || dm1.n != dm2.n) greska (DIM); dm3 = stvori (dm1.m, dm1.n); for (i=0; i<dm3.m; i++) for (j=0; j<dm3.n; j++) dm3.a[i][j] = dm1.a[i][j] + dm2.a[i][j]; return dm3; } Din_mat razlika (Din_mat dm1, Din_mat dm2) { /* Razlika matrica. */ int i, j; Din_mat dm3; if (dm1.m!=dm2.m || dm1.n != dm2.n) greska (DIM); dm3 = stvori (dm1.m, dm1.n); for (i=0; i<dm3.m; i++) for (j=0; j<dm3.n; j++) dm3.a[i][j] = dm1.a[i][j] - dm2.a[i][j]; return dm3; } Din_mat proizvod (Din_mat dm1, Din_mat dm2) { /* Proizvod matrica. */ int i, j, k; Din_mat dm3; if (dm1.n!=dm2.m) greska (DIM); dm3 = stvori (dm1.m, dm2.n); for (i=0; i<dm3.m; i++) for (k=0; k<dm3.n; k++) for (dm3.a[i][k]=j=0; j<dm2.n; j++) dm3.a[i][k] += dm1.a[i][j] * dm2.a[j][k]; return dm3; }

Page 28: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

28

3. Zadaci za vežbu

1. Brojeve zapisane u sistemu s bazom 3 možemo prikazati kao povezanu listu, čije ćelije su zapisi sa

dve komponente: cifra, pointer na iduću ćeliju. Glava liste (header) pokazuje na najmanje značajnu

cifru (cifru najmanje težine). Napišite potrebnu definiciju tipa podatka BASE3NUMBER. Zatim

napišite potprogram za sabiranje dva broja zapisanih u bazi 3.

2. Data je sortirana jednostruko povezana linearna lista. Ubaciti novi element u listu, tako da ona i

dalje ostane sortirana. Napisati funkcije za kreiranje i štampanje elemenata linearne liste, kao i

traženu funkciju za ubacivanje elementa u listu.

typedef struct cvor { int br; struct cvor* sl;

} CVOR;

#include <stdio.h> #include <stdlib.h> typedef struct cvor{ int broj; struct cvor *sled; } Cvor; void pisi (Cvor *lst); Cvor *umetni (Cvor *lst, int b,int n); void pisi (Cvor *lst) { if (lst) { printf ("%d ", lst->broj); pisi (lst->sled); } } Cvor *umetni (Cvor *lst, int b,int n) { Cvor *tek = lst, *pret = NULL, *novi; while(tek && tek->broj < b){ pret = tek; tek = tek->sled; } novi =(Cvor*)malloc (n*sizeof(Cvor)); novi->broj = b; novi->sled = tek; if(!pret) lst = novi; else pret->sled = novi; return lst;

}

3. Element INFO jednostruko povezane liste je tipa char* (C-string). Napisati C-funkciju 'izdvoji' koja iz ulazne

jednostru ko povezane liste izdvaja u novu izlaznu jednostruko povezanu listu sve elemente čiji INFO počinje

Page 29: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

29

sa zadatim uzorkom. Funkcija ima sledeći prototip:

typedef struct _jpl {

char *info; struct _jpl* link;

} JPL_T; JPL_T* izdvoji(JPL_T **ulLista, const char *uzorak);

#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct _jp1 { char *info; struct _jp1* link; } JPL_T; void ucitajInfo(char **s){ *s=NULL; char c; int n=0; c = getchar(); if(c=='\n') c=getchar(); while((c!=' ')&&(c!='\n')){ n++; *s=(char*)realloc(*s,n*sizeof(char)); *(*s+n-1)=c; c = getchar(); } *(*s+n)='\0'; } JPL_T* izdvoji(JPL_T *ulLista, const char *uzorak) { JPL_T *prvi = NULL, *posl = NULL; while(ulLista) { if(strstr(ulLista->info, uzorak)==ulLista->info) { JPL_T *novi = (JPL_T *)malloc (sizeof(JPL_T)); novi->info = ulLista->info; novi->link = NULL; if (!prvi) prvi = novi; else posl->link = novi; posl = novi; } ulLista = ulLista->link; } return prvi; } void ispisi(JPL_T *lst){ while(lst){ printf("%s ",lst->info); lst = lst -> link; } } JPL_T *ucitaj (int n) { JPL_T *prvi = NULL, *posl = NULL;

Page 30: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

30

int i; for (i=0; i<n; i++) { JPL_T *novi = (JPL_T *)malloc (sizeof(JPL_T)); ucitajInfo(&(novi->info)); novi->link = NULL; if (!prvi) prvi = novi; else posl->link = novi; posl = novi; } return prvi; }

4. Dat je pokazivač na kraj dvostruko povezane liste celih brojeva. Napisati funkciju koja će prvi čvor

prebaciti na poslednje mesto.

5. Napisati program koji računa n-ti izvod polinoma zapisanog u obliku P(x) = anxn + ... + a1x + a0. Polinom

se zadaje povezanom listom gde je prvi element liste slobodan član. Štampati dobijeni rezultat.

#include <stdio.h> #include <stdlib.h> struct polinom{ int stepenX; long koeficijent; struct polinom* sledeci; }; typedef struct polinom Polinom; Polinom* ucitavanjePolinoma(){ int stepen,koef; Polinom * tekuci, *start,*novi; tekuci =(Polinom*) malloc(sizeof(Polinom)); start = tekuci; tekuci->sledeci = NULL; puts("Unesite polinom:"); while(1){ printf("\nKoeficijent: "); scanf("%d",&koef); if(!koef) break; printf("\nStepen: "); scanf("%d",&stepen); novi = (Polinom*) malloc(sizeof(Polinom)); novi->koeficijent = koef; novi->stepenX = stepen; novi->sledeci = NULL; tekuci->sledeci = novi; tekuci = novi; } return start; } Polinom* izvodPolinoma(Polinom* pol){ Polinom* temp; temp = pol->sledeci; while(temp){ temp->koeficijent *= temp->stepenX; temp->stepenX--; temp = temp->sledeci; } }

Page 31: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

31

void stampajPolinom(Polinom* pol){ Polinom* temp; temp = pol->sledeci; while(temp){ if(temp->stepenX == 0){ printf("%d ",temp->koeficijent); } else { printf("%da^%d ",temp->koeficijent,temp->stepenX); } temp = temp->sledeci; if(temp) printf("+ "); } puts(""); } void ukloni(Polinom* pol){ Polinom * temp; while(pol){ temp = pol; pol = pol->sledeci; free(temp); } } void brisiClanSaNulomUKoeficijentu(Polinom* pol){ Polinom* prvi,*drugi; prvi = pol; drugi = prvi->sledeci; while(drugi){ if(drugi->koeficijent == 0){ prvi->sledeci = drugi->sledeci; free(drugi); drugi = prvi->sledeci; } else{ prvi = drugi; drugi = drugi->sledeci; } } } void nTiIzvodPolinoma(int n,Polinom* pol){ int i; for(i = 0; i < n; i++){ izvodPolinoma(pol); brisiClanSaNulomUKoeficijentu(pol); } }

6. Implementirati STACK pomoću jednostruko povezane liste (deklarisati potrebne tipove podataka i napisati

funkcije PUSH i POP), a zatim napisati funkciju koja računa izraz zadan u postfiksnoj notaciji koristeći već

implementirani STACK.

7. Implementirati jednostruko povezanu listu LIST pomoću pokazivača (deklarisati potrebne tipove podataka) čiji su elementi celi brojevi, a zatim napisati funkciju koja u datu sortiranu povezanu listu ubacuje elemente druge povezane liste, tako da lista ostaje sortirana.

Page 32: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

32

8. U stek realizovan poljem smeštju se celobrojni podaci (int). Napisati funkcije za stavljanje novog elementa na stek i skidanje elementa sa vrha steka koje vraćaju 1 ako su uspešno obavile posao, a 0 inače. Ukoliko je prilikom skidanja nekog elementa sa steka barem 20 elemenata steka slobodno, stek treba smanjiti za 10 elemenata. Ukoliko kod stavljanja elementa na stek više nema slobodnog prostora, stek uvećati za 10 elemenata. Funkcije moraju imati prototip: int stavi(int element, int **stog, int *max, int *vrh); int skini(int *element, int **stog, int *max, int *vrh);

#include <stdio.h> #include <stdlib.h> int *stog; int max = 0; int vrh = 0; int stavi(int element, int **stog, int *max, int *vrh){ if (*vrh < *max) (*stog)[(*vrh)++] = element; else { int *pom; pom = NULL; if ((pom = (int*)(malloc((*vrh) * sizeof(int)))) == NULL) return 0; for (int i=0; i < *vrh; i++) pom[i] = (*stog)[i]; free(*stog); *max = *max + 10; if ((*stog = (int *)(malloc(*max * sizeof(int)))) == NULL) return 0; for (int i=0; i < *vrh; i++) (*stog)[i] = pom[i]; free(pom); (*stog)[(*vrh)++] = element; } return 1; } int skini(int *element, int **stog, int *max, int *vrh){ if ((*stog == NULL)||(*vrh == 0)) return 0; *element = (*stog)[--*vrh]; if (*max - *vrh > 19){ int *pom; pom = NULL; if ((pom = (int *)(malloc(*vrh * sizeof(int)))) == NULL) return 0; for (int i=0; i < *vrh; i++) pom[i] = (*stog)[i]; free(*stog); *max = *max - 10; if ((*stog = (int *)(malloc(*max * sizeof(int)))) == NULL) return 0; for (int i=0; i < *vrh; i++) (*stog)[i] = pom[i]; free(pom); } return 1; }

Page 33: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

33

9. Napisati rekurzivnu funkciju koja će sadržaj jednostruko povezane liste prepisati u novu jednostruko povezanu listu na način da obrne poredak elemenata (prvi element u izvorišnoj listi postaje poslednji element u odredišnoj itd.). U postojeću jednostruko povezanu listu upisani su elementi tipa int. Funkcija mora vraćati 1 ukoliko je uspešno obavila posao, a 0 inače i imati prototip: int obrni(zapis **izvor, zapis **odrediste)

#include <stdio.h> #include <stdlib.h> typedef struct elem { int broj; struct elem *sled; } Elem; int obrni(Elem **izvor, Elem **odrediste){ int k=0; Elem *m=(Elem *)malloc (sizeof(Elem)); if (*izvor){ m->broj=(*izvor)->broj; m->sled=(*izvor)->sled; } else {m=NULL;k=1;} if (m){ Elem *novi = (Elem *)malloc (sizeof(Elem)); novi->broj = m->broj; novi->sled = *odrediste; *odrediste=novi; m=m->sled; k=obrni(&m,odrediste); } return k; } Elem *na_kraj (Elem *lst, int b) { if (!lst) { lst =(Elem *) malloc (sizeof(Elem)); lst->broj = b; lst->sled = NULL; } else lst->sled = na_kraj (lst->sled, b); return lst; } void pisi (Elem *lst) { if (lst) { printf ("%d ", lst->broj); pisi (lst->sled); } } void main () { Elem *lst = NULL; int kraj = 0, izbor, broj, n,k;Elem *lst1 = NULL; while (!kraj) { printf ("\n1. Dodavanje broja na kraj liste\n" "2. Ispisivanje liste\n" "3. Obrtanje i ispisivanje liste\n" "0. Zavrsetak rada\n\n" "Vas izbor? " ); scanf ("%d", &izbor); switch (izbor) { case 1: printf ("Broj? "); scanf ("%d", &broj); lst = na_kraj (lst, broj); break;

Page 34: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

34

case 2: /* Ispisivanje liste: */ printf ("Lista= "); pisi (lst); putchar ('\n'); break; case 3: { k=obrni(&lst, &lst1); printf ("Lista= "); pisi (lst1); putchar ('\n'); printf(" %d\n",k); break; } case 0: /* Zavrsetak rada: */ kraj = 1; break; default: /* Pogresan izbor: */ printf ("*** Neozvoljeni izbor! ***\a\n"); break; } } }

Napomene: Odredišna jednostruko povezana lista je na početku prazna. Izvorišna lista nakon izvršavanja funkcije treba ostati očuvana.

10. Napisati rekurzivnu funkciju koja će sadržaj dvostruko povezane liste prepisati u novu, jednostruko povezanu listu zadržavajući njihov poredak iz dvostruko povezane liste gledano od njene glave. U postojeću dvostruko povezanu listu upisani su elementi tipa int. Funkcija mora vraćati 1 ukoliko je uspešno obavila posao, a 0 inače i imati prototip:

int prepisi(zapisj **glavaJednostruka, zapisd **dvostrukaGlava, zapisd **dvostrukaRep) Napomene: Jednostruko povezana lista je prazna na početku. Početna dvostruko povezana lista nakon izvršavanja funkcije treba ostati očuvana.

#include <stdio.h> #include <stdlib.h> typedef struct jedlist{ int broj; struct jedlist *sledeci; }zapisj; typedef struct dvolist{ int broj; struct dvolist *sledeci; struct dvolist *prethodni; }zapisd; int ucitaj(zapisd **dvostrukaGlava,zapisd **dvostrukaRep, int brEl){ if(brEl==0)return 1; *dvostrukaGlava=(zapisd*)malloc(sizeof(zapisd)); *dvostrukaRep=*dvostrukaGlava; (**dvostrukaGlava).sledeci=NULL; (**dvostrukaGlava).prethodni=NULL; if(*dvostrukaGlava==NULL)return 0; scanf("%d",&(**dvostrukaGlava).broj); if(ucitaj(&(**dvostrukaGlava).sledeci, dvostrukaRep, brEl-1)){ if((**dvostrukaGlava).sledeci!=NULL)(*(**dvostrukaGlava).sledeci).prethodni=(*dvostrukaGlava); return 1;

Page 35: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

35

}else return 0; } int prepisi(zapisj **glavaJednostruka, zapisd **dvostrukaGlava, zapisd **dvostrukaRep){ if(*dvostrukaGlava==NULL) return 1; *glavaJednostruka=(zapisj*)malloc(sizeof(zapisj)); if(*glavaJednostruka==NULL)return 0; (**glavaJednostruka).broj=(**dvostrukaGlava).broj; (**glavaJednostruka).sledeci=NULL; return(prepisi(&(**glavaJednostruka).sledeci, &(**dvostrukaGlava).sledeci, dvostrukaRep)); } void ispisi(zapisj *glavaJednostruka){ if(glavaJednostruka==NULL){ printf("\n"); return; } printf("%d ",(*glavaJednostruka).broj); ispisi((*glavaJednostruka).sledeci); } int main(){ int brEl; zapisj *glavaJednostruka; zapisd *dvostrukaGlava,*dvostrukaRep; printf("Unesite broj elemenata dvostruko povezane liste:\n"); scanf("%d",&brEl); printf("Unesite redom sve elemente dvostruko povezane liste:\n"); if(ucitaj(&dvostrukaGlava, &dvostrukaRep, brEl)==0){ printf("Ne moze se obezbediti dovoljno memorije za izvrsenje zadatka. Prekid programa.\n"); return 1; } if(prepisi(&glavaJednostruka, &dvostrukaGlava, &dvostrukaRep)==0){ printf("Ne moze se obezbediti dovoljno memorije za izvrsenje zadatka. Prekid programa.\n"); return 2; } ispisi(glavaJednostruka); return 0; }

11. U jednostruko povezanu listu čuvaju se podaci o ispitima: matični broj studenta (long), šifra predmeta (int) i ocjena (short). Ocjena 0 označava da student nije pristupio ispitu (a prijavio ga je). Napisati funkciju koja će iz liste izbaciti sve zapise s ocjenom 0. Funkcija mora vratiti broj izbačenih zapisa i mora imati prototip:

int izbaci(zapis **glava);

12. U dvostruko povezanu linearnu listu LIST smeštaju se podaci o procesima koji čekaju na

izvršavanje: identifikator procesa (celi broj), prioritet procesa (celi broj), vlasnik procesa (polje znakova) i vreme pokretanja procesa (polje znakova). Lista je uređena prema prioritetu procesa (procesi sa najvećim prioritetom nalaze se na početku). Potrebno je napisati funkciju koja će zadanom procesu s identifikatorom idprocesa promeniti prioritet u prioritet i ponovno urediti listu prema prioritetu procesa. Funkcija treba imati prototip: void SetAndSort(LIST* lista, int idprocesa, int prioritet);

#include<stdio.h> #include<stdlib.h> #include<string.h>

Page 36: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

36

typedef struct listacv LIST; /*dvostruko povezana linearna lista*/ struct listacv{ int id; /*informaciono polje je clan niza x*/ int pr; char vl[30]; LIST *sledeci, *prethodni; }; LIST *lista, *kraj; LIST *ubaci(LIST *kraj, int id1, int pr1, char *vl1){ LIST *novi; /*novi cvor za umetanje u listu*/ novi=(LIST *)malloc(sizeof(LIST)); /*alokacija memorije za novi cvor liste*/ novi->id=id1; /*inicijalizacija polja u cvoru novi */ novi->pr = pr1; strcpy(novi->vl, vl1); novi->sledeci=NULL; novi->prethodni=kraj; /*novi element se dodaje na kraj postojece liste*/ kraj->sledeci=novi; /* do tada poslednji cvor kraj je ispred clana novi*/ kraj=novi; /*poslednji dodat element je novi kraj liste*/ return kraj; } void Izbaci(LIST *el){ if (el->prethodni == NULL){ //Ako je el na pocetku liste onda stavljamo da je el->sledeci na pocetku liste lista = el->sledeci; lista->prethodni = NULL; return; } if (el->sledeci == NULL){ //Ako je el na kraju liste onda stavljamo da je el->prethodni na kraju liste kraj = el->prethodni; kraj->sledeci = NULL; return; } LIST *pret, *sled; pret = el->prethodni; sled = el->sledeci; pret->sledeci = sled; //Ako je el bio u sredini liste onda stavimo da je sledbenik pret-a sled sled->prethodni = pret; return; } void UbaciNaMesto (LIST *el){ LIST *trazi; trazi = lista; if (lista->pr < el->pr){ //Ako el ima veci prioritet od prvog cvora liste onda stavimo el->sledeci = lista; //el na pocetak liste el->prethodni = NULL; lista->prethodni = el; lista = el; return; } if (kraj->pr > el->pr){ //Ako el ima manji prioritet od poslednjeg cvora liste onda stavimo el->prethodni = kraj; //el na kraj liste el->sledeci = NULL;

Page 37: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

37

kraj->sledeci = el; kraj = el; return; } trazi = lista->sledeci; while (trazi->pr > el->pr) //Pronadjemo prvi cvor liste koji nema prioritet veci od el-a i to je trazi trazi = trazi->sledeci; LIST *pret; pret = trazi->prethodni; //Postavimo el izmedju trazi->prethodnik i trazi pret->sledeci = el; el->prethodni = pret; el->sledeci = trazi; trazi->prethodni = el; return; } void SetAndSort (LIST *lista, int idprocesa, int prioritet){ LIST *trazi; trazi = lista; while (trazi->id != idprocesa){ //Pronadjemo cvor liste ciji id = idprocesa trazi = trazi->sledeci; } Izbaci (trazi); //Iz liste izbacimo cvor koji smo nasli trazi->pr = prioritet; //promenimo mu prioritet UbaciNaMesto(trazi); //i ubacimo na odgovarajuce mesto u listi. } int main(){ //LIST *kraj; int idu; int pru; char vlu[30]; int idprocesa, prioritet; FILE *ulaz; ulaz=fopen("procesi.txt", "r"); fscanf (ulaz, "%d%d", &idprocesa, &prioritet); fscanf(ulaz, "%d%d%s", &idu, &pru, vlu); lista=(LIST*)malloc(sizeof(LIST)); lista->id = idu; lista->pr = pru; strcpy(lista->vl, vlu); lista->sledeci = NULL; lista->prethodni = NULL; kraj = lista; while (!feof(ulaz)){ fscanf(ulaz, "%d%d%s", &idu, &pru, vlu); kraj=ubaci (kraj, idu, pru, vlu); //n++; } fclose(ulaz); //Pretpostavimo da u listi sigurno postoji proces ciji je id = idprocesa

Page 38: 1.1. 1BPOLJE - Наставнички порталnasport.pmf.ni.ac.rs/materijali/1263/Linearne strukture.pdf · 2013. 2. 25. · 1 1. 0BLINEARNE STRUKTURE PODATAKA 1.1. 1BPOLJE 1.1.1.

38

SetAndSort(lista, idprocesa, prioritet); LIST *s; s = lista; FILE *izlaz; izlaz = fopen("izlaz.out", "w"); while (s!=NULL){ fprintf(izlaz, "%d %d %s\n", s->id, s->pr, s->vl); s = s->sledeci; } fclose(izlaz); return 0;

}