Strukture podataka¶
Autor zadatka: Relja Mihić <relja.mihic@uns.ac.rs>
Ime ulazne datoteke učitati argumentom komandne linije. Ulazna datoteka sadrži podatke strukturama podataka:
naziv
(jedna reč, do 40 karaktera)memorija_elementa
(ceo broj, u bajtima)prosecno_trajanje_pretrage
(jedna reč, do 3 karaktera)
Učitati podatke u jednostruko spregnutu listu dodavanjem novih elemenata na kraj liste. U izlaznu datoteku pod nazivom memorija.txt
ispisati imena i ukupno memorije potrebno za čuvanje broja elemenata učitanog preko argumenta komandne linije. Memoriju izraziti u kilobajtima (kB), ako važi da je 1kB = 1024bajta. Za uneti broj elemenata, ispisati na standardnom izlazu za svaku strukturu vreme prosečne pretrage, ako:
1
- je potrebna jedna operacija, otpr. 5 nanosekundilog
- je potrebno 5 * log(n) nanosekundin
- je potrebno 5 * n nanosekundi
U slučaju uspešnog izvršavanja programa, izaći sa status kodom 0
(EXIT_SUCCESS
).
Ukoliko program ne može da se izvrši do kraja usled sledećih nedostataka, izaći iz programa sa sledećim status kodovima:
U slučaju nedovoljnog ili suvišnog broj argumenata komandne linije, izaći iz programa status kodom
1
(EXIT_FAILURE
)Ako nije uspešno otvorena ulazna datoteka, izaći iz programa sa status kodom
2
Ako nije uspešno otvorena izlazna datoteka, izaći iz programa sa status kodom
3
Ako nije uspešno alocirana memorija za elemente, izaći iz programa sa status kodom
4
Primer poziva programa:
./a.out strukture.txt 1000
Primer ulazne datoteke strukture.txt
:
Niz 52 n
Binarno_stablo_pretrage 72 log
Jednostruko_spregnuta_lista 64 n
Hes_tabela 64 1
Dvostruko_spregnuta_lista 72 n
AVL_stablo 80 log
Ispis programa na standardnom izlazu:
Prosecno vreme pretrage:
Niz - 5000 ns
Binarno_stablo_pretrage - 34.54 ns
Jednostruko_spregnuta_lista - 5000 ns
Hes_tabela - 5 ns
Dvostruko_spregnuta_lista - 5000 ns
AVL_stablo - 34.54 ns
Primer izlazne datoteke memorija.txt
:
Niz 50.78kB
Binarno_stablo_pretrage 70.31kB
Jednostruko_spregnuta_lista 62.50kB
Hes_tabela 62.50kB
Dvostruko_spregnuta_lista 70.31kB
AVL_stablo 78.12kB
Primer rešenja¶
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <math.h>
5
6#define MAX_NAZIV 41
7#define MAX_SEARCH 4
8
9typedef struct cvor_st {
10 char naziv[MAX_NAZIV];
11 int mem;
12 char search[MAX_SEARCH];
13 struct cvor_st *sledeci;
14} CVOR;
15
16FILE *safe_fopen(char *ime, char *rezim, int kod_greske);
17void inicijalizacija(CVOR **glava);
18void ucitavanje(CVOR **glava, FILE *pf);
19CVOR *napravi_cvor(char *ime, int m, char *alg);
20void dodaj_na_kraj(CVOR **glava, CVOR *novi);
21void ispis_memorija(FILE *pf, CVOR *glava, int uneta_vel);
22void ispis_trajanja(CVOR *glava, int uneta_vel);
23void obrisi_listu(CVOR **glava);
24
25int main(int argc, char **argv) {
26
27 if (argc != 3) {
28 printf("Primer poziva programa: %s strukture.txt 1000\n", argv[0]);
29 exit(1);
30 }
31
32 CVOR *glava;
33 FILE *ulazna, *izlazna;
34
35 inicijalizacija(&glava);
36 ulazna = safe_fopen(argv[1], "r", 2);
37 ucitavanje(&glava, ulazna);
38 fclose(ulazna);
39
40 izlazna = safe_fopen("memorija.txt", "w", 3);
41 ispis_memorija(izlazna, glava, atoi(argv[2]));
42 fclose(izlazna);
43
44 ispis_trajanja(glava, atoi(argv[2]));
45 obrisi_listu(&glava);
46
47 return 0;
48}
49
50FILE *safe_fopen(char *ime, char *rezim, int kod_greske) {
51 FILE *pf = fopen(ime, rezim);
52
53 if (pf == NULL) {
54 printf("Nije otvoren %s", ime);
55 exit(kod_greske);
56 }
57
58 return pf;
59}
60
61void inicijalizacija(CVOR **glava) {
62 *glava = NULL;
63}
64
65void ucitavanje(CVOR **glava, FILE *pf) {
66 char ime[MAX_NAZIV], alg[MAX_SEARCH];
67 int m;
68
69 while(fscanf(pf, "%s %d %s", ime, &m, alg) != EOF) {
70 CVOR *novi = napravi_cvor(ime, m, alg);
71 dodaj_na_kraj(glava, novi);
72 }
73}
74
75CVOR *napravi_cvor(char *ime, int m, char *alg) {
76 CVOR *novi = (CVOR *)malloc(sizeof(CVOR));
77
78 if (novi == NULL) {
79 printf("Nema dovoljno memorije!\n");
80 exit(4);
81 }
82
83 strcpy(novi->naziv, ime);
84 strcpy(novi->search, alg);
85 novi->mem = m;
86 novi->sledeci = NULL;
87
88 return novi;
89}
90
91void dodaj_na_kraj(CVOR **glava, CVOR *novi) {
92 if (*glava == NULL) {
93 *glava = novi;
94 } else {
95 CVOR *trenutni = *glava;
96 while(trenutni->sledeci != NULL) {
97 trenutni = trenutni->sledeci;
98 }
99 trenutni->sledeci = novi;
100 }
101}
102
103void obrisi_listu(CVOR **glava) {
104 while(*glava != NULL) {
105 CVOR *trenutni = *glava;
106 *glava = trenutni->sledeci;
107 trenutni->sledeci = NULL;
108 free(trenutni);
109 }
110}
111
112void ispis_memorija(FILE *pf, CVOR *glava, int uneta_vel) {
113 CVOR *tr = glava;
114 while(tr != NULL) {
115 fprintf(pf, "%s %.2lfkB\n", tr->naziv, tr->mem * uneta_vel / 1024.0);
116 tr = tr->sledeci;
117 }
118}
119
120void ispis_trajanja(CVOR *glava, int uneta_vel) {
121 CVOR *trenutni = glava;
122 printf("Prosecno vreme pretrage:\n");
123 while(trenutni != NULL) {
124 if(strcmp(trenutni->search, "1") == 0) {
125 printf("%s - %d ns\n", trenutni->naziv, 5);
126 } else if(strcmp(trenutni->search, "log") == 0) {
127 printf("%s - %.2f ns\n", trenutni->naziv, 5.0 * log(uneta_vel));
128 } else if(strcmp(trenutni->search, "n") == 0) {
129 printf("%s - %d ns\n", trenutni->naziv, 5 * uneta_vel);
130 }
131 trenutni = trenutni->sledeci;
132 }
133}