slide1 n.
Download
Skip this Video
Download Presentation
Još primjera rekurzije (s predavanja)

Loading in 2 Seconds...

play fullscreen
1 / 16

Još primjera rekurzije (s predavanja) - PowerPoint PPT Presentation


  • 56 Views
  • Uploaded on

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Još primjera rekurzije (s predavanja)' - skip


Download Now An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1
Napisati funkciju za punjenje memorijski rezidentnog binarnog stabla u čije čvorove treba upisati: cijena artikla (realni broj) i naziv artikla (15+1 znakova). Stablo treba sortirati po cijeni artikala; lijevi jeftiniji, desni skuplji. Napisati funkciju za ispis elementa za koju je ulazni argument korijen stabla. Ispis treba biti poredan po cijeni od najjeftinijeg do najskupljeg artikla. Napisati funkciju koja ispiše sve proizvode čija je cijena manja od neke određene vrijednosti koja se unese u glavnoj funkciji programa tijekom izvršavanja programa.

Zadatak preuzeo Danijel Markić

  • U memoriji napraviti binarno stablo traženja u čije čvorove se upisuju 2 podatka: prvi tipa int i drugi tipa float. Stablo se sortira prema cjelobrojnom podatku (lijevo manji, desno veći). Ispisati BST po algoritmu INORDER. Napisati funkcije MIN() i MAX() koje u najmanjem mogućem broju koraka (u najkraćem mogućem vremenu izvršavanja) moraju naći i ispisati zapise koji odgovaraju najmanjoj i najvećoj cjelobrojnoj vrijednosti (nije dopušteno pročitati zapise u svim čvorovima). U programu zatim izbrisati čvorove koji odgovaraju tim zapisima te ispisati tako nastalo BST u INORDER algoritmu. Napisati funkciju koja izračuna i ispiše prosječnu vrijednost varijable tipa float u BST.

Zadatak slobodan

slide2
Napisati program koji od ulaznog polja cijelih brojeva izgradi minimalnu hrpu (u korijenu je najmanji element), te ispiše polje u kojem su spremljeni elementi hrpe. Također napraviti silazno sortiranje (od najvećeg elementa prema najmanjem) polja cijelih brojeva upotrebom sortiranja pomoću hrpe.

Zadatak preuzeo: David Mihoci

  • Na web stranici kolegija (lnrpc2.irb.hr/soya/nastava/studenti.html) nalazi se popis svih studenata ovog kolegija koji su bili prisutni na bar jednom održavanju nastave, ukupno 29 studenata. Napisati program koji će iz datoteke pročitati imena i prezimena studenata i upisati ih po abecedi (po prezimenima) u listu čiji su elementi oblika ime (20 znakova), prezime (20 znakova). Elemente te liste treba prekopirati i složiti u red upotrebom generatora slučajnih brojeva (npr. prvi generirani broj je 13, tada je prvi element reda student koji je na poziciji 13 u listi, pa drugi generirani broj 7 daje da je drugi student u redu onaj koji je 7 u listi itd) tako da se svaki student pojavljuje na samo jednom mjestu u redu. Elementi reda su oblika ime (20 znakova), prezime (20 znakova), zadatak (short). Vrijednost varijable zadatak (kratki cijeli broj) za svaki element liste mora biti od 1 do 40 i njih treba upisati (svaki broj samo jednom, bez ponavljanja istih brojeva) u red također koristeći generator slučajnih brojeva (npr. ako je prvi generirani broj 17 tada taj broj ide uz studenta koji je prvi u redu itd). Tako dobiven red treba ispisati u obliku: ime, prezime, zadatak.

Zadatak slobodan

jo primjera rekurzije s predavanja
Još primjera rekurzije (s predavanja)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAXA 10

// ispis znaka c u zadanoj duljini n

void nznak (int c, int n) {

while (--n >= 0) putchar(c);

}

// ispis polja

void ispisi(int A[], int n) {

int i;

printf("\n");

for (i = 0; i < n; i++) printf(" A[%d]",i);

printf("\n");

for (i = 0; i < n; i++) printf("%5d", A[i]);

printf("\n");

}

slide4
// Rekurzivno trazenje indeksa clana u polju

int trazi (int A[], int x, int n, int i) {// A-polje x-trazeni i-indeks od kojeg se trazi

int ret;

nznak(' ', i*5); printf("^^^^^\n");

if (i >= n) ret = -1;

else if (A[i] == x) ret = i;

else ret = trazi (A, x, n, i+1);

nznak(' ', i*5); printf("%5d\n", ret);

return ret;

}

// Rekurzivno trazenje indeksa clana u polju s ogranicivacem

int trazi1 (int A[], int x, int i){

int ret;

nznak(' ', i*5); printf("^^^^^\n");

if(A[i] == x) ret = i;

else ret= trazi1 (A, x, i+1);

nznak(' ', i*5); printf("%5d\n", ret);

return ret;

}

slide5
// Rekurzivno trazenje najveceg clana polja

int maxclan (int A[], int i, int n) {

int imax;

if (i >= n-1) return n-1;

imax = maxclan (A, i + 1, n);

if (A[i] > A[imax]) return i;

return imax;

}

// Rekurzivno trazenje najveceg clana polja - strukturirano

int maxclan1 (int A[], int i, int n) {

int imax, ret;

printf ("max(%d) -> ", i);

if (i >= n-1) {

printf ("\n");

ret = n-1;

} else {

imax = maxclan1 (A, i + 1, n);

if (A[i] > A[imax]) ret = i;

else ret = imax; }

printf ("<- max(%d)=%d ", i, ret);

return ret;}

slide6
// macro naredba za vecu od dvije vrijednosti

#define maxof(a,b) ((a) > (b) ? (a) : (b))

// Funkcija s macro naredbom koja vraca vrijednost najveceg clana

int maxclan2 (int A[], int i, int n) {

int m;

if (i >= n-1) return A[i];

m = maxclan2 (A, i + 1, n);

return maxof(A[i], m);

}

// Primjer neispravne rekurzije

int los (int n, int *dubina) {

int r;

(*dubina)++;

printf ("n = %d, dubina rekurzije = %d\n", n, *dubina);

if (n == 0)

r = 0;

else

r = los (n / 3 + 1, dubina) + n - 1;

return r;

}

slide7
void main (void) {

int A[MAXA], x, i, n, dubina;

FILE *fi;

fi = fopen ("UlazZaRekurzije.txt", "r");

if (!fi) exit (1);

n = 0;

while (n < MAXA - 1 && fscanf (fi, "%d", &A[n]) != EOF) n++;

fclose (fi);

ispisi (A, n);

printf ("Upisite vrijednost za x =");scanf ("%d", &x);

printf ("\nRekurzivno trazenje indeksa clana\n");

ispisi (A, n);

if ((i = trazi (A, x, n, 0)) < 0) {

printf ("Vrijednost %d ne postoji u polju\n", x);

} else {

printf ("A [%d] = %d\n", i, A [i]); }

printf ("\nRekurzivno trazenje ... s ogranicivacem\n");

A [n] = x; // postavljanje ogranicivaca

ispisi (A, n+1);

if ((i = trazi1 (A, x, 0)) == n) {

printf ("Vrijednost %d ne postoji u polju", x);

} else {

printf ("A [%d] = %d\n", i, A [i]); }

slide8
printf ("\nRekurzivno trazenje najveceg...\n");

ispisi(A, n);

if ((i = maxclan (A, 0, n)) != maxclan1 (A, 0, n)) {

printf ("Pogreska: Strukturirana i nestrukturirana funkcija daju razlicite rezultate!\n");

exit (0);

}

printf ("\nNajveci clan A [%d] = %d\n",i, A [i]);

printf ("Funkcija s macro naredbom je nasla najveci clan %d\n", maxclan2 (A, 0, n));

printf ("\nPozivam neispravnu rekurziju\n");

while (1) {

dubina = 0;

printf ("Upisite vrijednost za n =");

scanf ("%d", &n);

i = los (n, &dubina);

printf ("\ni = %d", i);

}

exit(0);

}

sortiranje spajanjem merge sort
Sortiranje spajanjem (merge sort)
  • Algoritam sortiranja sažimanjem:

ulaz je lista a1, …, an , izlaz sortirana lista

1. podijeli listu na dva jednaka dijela

2. sortiraj listu a1, …, an/2

3. sortiraj listu an/2+1, …, an

4. spoji liste a1, …, an/2 i an/2+1, …, an

  • Algoritam sažimanja:

ulaz su dvije sortirane liste b1, …, bk i c1, …, cl , izlaz je sortirana lista a1, …, ak+l

1. i = 1, j = 1

2. ponavljaj korak 3 sve dok je i ≤ k i j ≤ l

3. ako je bi < cj onda ai+j-1 = bi, i=i+1, inače ai+j-1 = cj, j=j+1

4. ponavljaj korak 5 sve dok je i ≤ k

5. ai+j-1 = bi, i=i+1

6. ponavljaj korak 7 sve dok je j ≤ l

7. ai+j-1 = cj, j=j+1

  • Složenost ovog algoritma je O(n lg n)
  • Nedostatak: potrebno pomoćno polje
slide10
#include <stdlib.h>

#include <stdio.h>

#include <time.h>

typedef int tip;

// udruzivanje LPoz:LijeviKraj i DPoz:DesniKraj

void Merge (tip A [], tip PomPolje [], int LPoz, int DPoz, int DesniKraj) {

int i, LijeviKraj, BrojClanova, PomPoz;

LijeviKraj = DPoz - 1;

PomPoz = LPoz;

BrojClanova = DesniKraj - LPoz + 1;

while (LPoz <= LijeviKraj && DPoz <= DesniKraj) {// glavna petlja

if (A [LPoz] <= A [DPoz])

PomPolje [PomPoz++] = A [LPoz++];

else

PomPolje [PomPoz++] = A [DPoz++];

}

while (LPoz <= LijeviKraj) // Kopiraj ostatak prve polovice

PomPolje [PomPoz++] = A [LPoz++];

while (DPoz <= DesniKraj) // Kopiraj ostatak druge polovice

PomPolje [PomPoz++] = A [DPoz++];

for (i = 0; i < BrojClanova; i++, DesniKraj--) // Kopiraj PomPolje natrag

A [DesniKraj] = PomPolje [DesniKraj];

}

slide11
// MergeSort - rekurzivno sortiranje podpolja

void MSort (tip A [], tip PomPolje[], int lijevo, int desno ) {

int sredina;

if (lijevo < desno) {

sredina = (lijevo + desno) / 2;

MSort (A, PomPolje, lijevo, sredina);

MSort (A, PomPolje, sredina + 1, desno);

Merge (A, PomPolje, lijevo, sredina + 1, desno);

}

}

// MergeSort - sort udruzivanjem

void MergeSort (tip A [], int N) {

tip *PomPolje;

PomPolje = malloc (N * sizeof (tip));

if (PomPolje != NULL) {

MSort (A, PomPolje, 0, N - 1);

free (PomPolje);

} else {

printf ("Nema mjesta za PomPolje!");

exit(1);}

}

slide12
void main (void) {

tip *Polje1,maxcl;

int Duljina,brojac;

printf ("Unesi broj clanova polja >");

scanf ("%d", &Duljina);

if ((Polje1 = (tip *) malloc (Duljina * sizeof (tip)))== NULL) {

printf("\nNema dovoljno memorije!\n");

exit(1); }

srand(time(NULL));

printf("\nUnesi maksimalnu vrijednost clanova>");

scanf("%d", &maxcl);

for (brojac=0; brojac<Duljina; brojac++){

Polje1[brojac]=(tip) maxcl * ((float)rand() / (RAND_MAX + 1));}

printf("\n Prije sortiranja:\n");

for (brojac=0; brojac<Duljina; brojac++)

printf("Polje[%d]=%d ",brojac,Polje1[brojac]);

printf("\n");

MergeSort(Polje1,Duljina);

printf("\n Nakon sortiranja:\n");

for (brojac=0; brojac<Duljina; brojac++)

printf("Polje[%d]=%d ",brojac,Polje1[brojac]);

printf("\n");

exit(0);}

problem hanojskih tornjeva
Problem hanojskih tornjeva
  • Napisati program koji rješava problem hanojskih tornjeva:
  • Štapovi S (source, izvor), D (destination, odredište), T(temp, pomoćni)
  • Na prvom štapu (S) ima n diskova različite veličine postavljenih tako da veći nikad ne dolazi iznad manjeg. Preseliti sve diskove na D, jedan po jedan, uvijek postavljajući manji na veći
  • Problem je zadao francuski matematičar Edouard Lucas 1883 godine
  • Školski primjer uspjeha rekurzivnog postupka
  • Algoritam rješenja:
  • Ignorirati donji (najveći) disk i riješiti problem za n-1 disk, ali sa štapa S na štap T koristeći D kao pomoćni.
  • Sada se najveći disk nalazi na S, a ostalih n-1 na T.
  • Preseliti najveći disk sa S na D.
  • Preseliti n-1 disk sa T na D koristeći S kao pomoćni (problem je već riješen za n-1 disk).
slide14
#include <stdio.h>

#include <stdlib.h>

void hanoii(char src, char dest, char tmp, int n) {

if (n > 0) {

hanoii(src, tmp, dest, n - 1);

printf("\nPrebacujem element %d s tornja %c na toranj %c", n, src, dest);

hanoii(tmp, dest, src, n - 1);

}

}

int main() {

int n ;

printf("\nHanojski tornjevi:");

printf("\n Unesi broj elemenata na tornjevima>");

scanf("%d",&n);

hanoii('S', 'D', 'T', n);

return 0;

}

slide15
Analiza algoritma: označimo s TN minimalan broj poteza potreban da se riješi problem s N diskova
  • za N=3, T3=7; za N=2, T2=3; N=1, T1=1 (T0=0)
  • Izloženi rekurzivni algoritam uključuje dva puta po N-1 pomicanje s jednog štapa na drugi i još jedno završno pomicanje diska. Ovo prebacivanje nije moguće obaviti u manje koraka, jer do trenutka kad je na štapu D ostao samo najdonji disk, potrebno je prebaciti N-1 diskova sa štapa S na štap T, a to se može obaviti u najmanje N-1 prebacivanja. Zatim se u jednom prebacivanju najdonji disk složi na štap D, a da bi se prebacilo N-1 diskova na štap D potrebno je opet najmanje N-1 koraka. Dakle vrijedi:

TN= 2TN-1+1, T0=0, T1=1

  • uvedemosupstituciju Sn = TN +1 i slijedi rekurzivna relacija

Sn= 2Sn-1, S0=0

  • Karakteristična jdba je x – 2 = 0 i njeno rješenje je x = 2, a rješenje homogene rekurzivne jdbe je

Sn= 2n , pa je

TN= 2N -1, N ≥ 0

slide16
Dakle, našli smo da vrijeme izvršavanja ovog algoritma raste eksponencijalno s brojem diskova
  • Stara legenda: u indijskom hramu stoje 3 stupa s 64 zlatna diska na jednom stupu. Svećenici u hramu imaju zadatak (dan od stvoritelja) da prebace diskove poštujući gornja pravila. Kad uspiju riješiti zadatak, svijet će propasti. Kad bi uspijevali prebacivati diskove brzinom od jednog diska u sekundi i to po algoritmu koji zahtjeva najmanji broj prebacivanja, bilo bi im potrebno 264-1 sekundi što je 585 milijardi godina (današnja starost svemira je oko 14 milijardi godina).
ad