/*
datoteke_txt_i_bin_-_lista_sa_string_string_int_float_v1.c
Datoteke i liste:
Kreira listu od nizova stringova, integer-a i float-a.
Cvorovi liste sadrze: string, string, int, float.
Upis liste u bin datoteku.
Citanje liste iz bin datoteke.
Upis liste u txt datoteku.
Citanje liste iz txt datoteke.
Sortiranje liste.
*/
#include <stdio.h>
#include<stdlib.h>
#include <string.h> // zbog strcpy()
#define MAX_SIZE 100 // niz moze imati najvise MAX_SIZE elemenata
#define TEKST_SIZE 30 // string moze imati najvise TEKST_SIZE karaktera
struct cvor{ // struktura cvor, to je jedan element liste,
char ime[TEKST_SIZE]; // ima svoj sadrzaj i
char prezime[TEKST_SIZE];
int brojInt;
float brojFloat;
struct cvor *sledeci; // pointer na sledeceg clana
};
typedef struct cvor CVOR; // jedan cvor liste CVOR
typedef CVOR* PCVOR; // pointer na listu CVOR
// Prikazuje opis liste i sadrzaj cvorova liste glava.
// Sa pomocnim cvorom tekuci (koji je ovde nepotreban, videti v1).
void prikazi_listu (char tekst[],PCVOR glava) {
PCVOR tekuci = glava; // pomocni cvor u kojem cuvamo glava da ne bi bila promenjena
// glava nije predata funkciji sa adresom, tako da nece biti promenjena, tekuci je nepotreban
printf("\n\n %s \n",tekst); // prikazuje opis liste
if(tekuci == NULL) { // ako nema cvorova u listi
printf("\n prazna. \n");
} else { // ako ima cvorova u listi
while(tekuci != NULL) { // od pocetka do kraja liste
printf("\n | %-6s %-8s %5d %6.2f \t adresa sledeceg %p | \n",
tekuci->ime,
tekuci->prezime,
tekuci->brojInt,
tekuci->brojFloat,
tekuci->sledeci );
tekuci = tekuci->sledeci; // idemo na sledeci cvor liste
}
}
}
// Prikazuje opis liste i sadrzaj cvorova liste glava.
// Bez pomocnog cvora tekuci.
// Glava nece biti promenjena jer nije predata sa adresom (PCVOR *glava).
// Pojednostavljena verzija koja nece ispisati listu ako je prazna.
void prikazi_listu_v1 (char tekst[],PCVOR glava) {
printf("\n\n %s \n",tekst); // prikazuje opis liste
while(glava != NULL) { // od pocetka do kraja liste
printf("\n | %-6s %-8s %5d %6.2f \t adresa sledeceg %p | \n",
glava->ime,
glava->prezime,
glava->brojInt,
glava->brojFloat,
glava->sledeci );
glava = glava->sledeci; // idemo na sledeci cvor liste
}
}
// Prikazuje jedan cvor KojiCvor (sadrzaj cvora i pointer na sledeci)
void prikazi_jedan_cvor (PCVOR KojiCvor) {
printf("\n");
if(KojiCvor == NULL) { // ako je cvor prazan
printf("\n Cvor je prazan. \n");
} else { // ako cvor nije prazan
printf("\n | %-6s %-8s %5d %6.2f \t adresa sledeceg %p | \n",
KojiCvor->ime,
KojiCvor->prezime,
KojiCvor->brojInt,
KojiCvor->brojFloat,
KojiCvor->sledeci );
}
}
// Vraca broj cvorova liste glava.
// Funkcija ne zavisi od sadrzaja cvorova liste glava.
int prebroj_cvorove_liste (PCVOR glava)
{
int BrojCvorova=0; // brojac cvorova
while(glava != NULL) { // od prvog do poslednjeg cvora liste glava
BrojCvorova++; // brojimo cvorove (uvecavamo brojac)
glava = glava->sledeci; // prelazimo na sledeci cvor
}
return BrojCvorova; // vraca broj cvorova liste glava
}
// U listi glava trazi cvor cije je prezime KojePrezime.
// Vraca 1 ako nadje takav cvor, inace vraca 0.
// strcmp(a,b) uporedjuje stringove a i b i vraca: ( CoMPare )
// -1 za a<b
// 0 za a=b
// 1 za a>b
int postoji_u_listi (PCVOR glava,char KojePrezime[])
{
while(glava){ // od pocetka do kraja liste
if( strcmp(glava->prezime, KojePrezime ) == 0 ) // USLOV PRETRAGE
return 1; // nadjen je takav cvor
/*
// ako trazimo podatak koji je int (slicno je i za podatak float)
if( glava->brojInt == KojiInt ) // USLOV PRETRAGE
return 1; // nadjen je takav cvor
*/
glava = glava->sledeci; // prelazimo na sledeci cvor
}
return 0; // prosli smo sve cvorove i nije nadjen je takav cvor
}
// U listi glava broji cvorove cije je prezime KojePrezime.
// Vraca broj takvih cvorova.
// strcmp(a,b) uporedjuje stringove a i b i vraca: ( CoMPare )
// -1 za a<b
// 0 za a=b
// 1 za a>b
int broj_pojavljivanja_u_listi (PCVOR glava,char KojePrezime[])
{
int BrojPojavljivanja=0; // brojac pojavljivanja takvih cvorova
while(glava){ // od pocetka do kraja liste
if( strcmp(glava->prezime, KojePrezime ) == 0 ) // USLOV PRETRAGE
BrojPojavljivanja++; // uvecavamo brojac
/*
// ako trazimo podatak koji je int (slicno je i za podatak float)
if( glava->brojInt == KojiInt ) // USLOV PRETRAGE
BrojPojavljivanja++; // uvecavamo brojac
*/
glava = glava->sledeci; // prelazimo na sledeci cvor
}
return BrojPojavljivanja; // vraca broj pojavljivanja takvih cvorova
}
// Na pocetak liste glava dodaje vec napravljeni novi cvor
// Funkcija ne zavisi od sadrzaja cvorova liste glava.
// Dobija se obrnuti redosled cvorova u odnosu na niz.
void dodaj_na_pocetak (PCVOR *glava, PCVOR *rep, PCVOR novi)
{
if(*glava == NULL) { // ako je lista prazna
*rep = novi; // i rep i glava su taj novi cvor
*glava = novi;
} else { // ako lista nije prazna
novi->sledeci = *glava; // sledeci od novog mora biti stara glava
*glava = novi; // nova glava je taj novi
}
}
// Na kraj liste glava dodaje vec napravljeni novi cvor
// Funkcija ne zavisi od sadrzaja cvorova liste glava.
// Dobija se isti redosled cvorova u odnosu na niz.
void dodaj_na_kraj (PCVOR *glava, PCVOR *rep, PCVOR novi)
{
if(*glava == NULL) { // ako je lista prazna
*rep = novi; // i rep i glava su taj novi cvor
*glava = novi;
} else { // ako lista nije prazna
(*rep)->sledeci = novi; // sledeci od starog repa je taj novi
*rep = novi; // novi rep je taj novi
}
}
// Kreira cvor novi sa sadrzajem, sledeci mu je NULL
void napravi_novi_cvor( PCVOR *novi,
char ime[TEKST_SIZE],
char prezime[TEKST_SIZE],
int brojInt,
float brojFloat )
{
*novi = (PCVOR)malloc(sizeof(CVOR)); // rezervisemo memoriju za cvor novi
if(*novi == NULL) { // obrada eventualne greske pri rezervisanju memorije
printf("\n Greska pri rezervisanju memorije! \n");
exit(1); // prekidamo program
}
strcpy( (*novi)->ime, ime ); // sa stringovima mora strcpy()
strcpy( (*novi)->prezime, prezime ); // sa stringovima mora strcpy()
(*novi)->brojInt = brojInt;
(*novi)->brojFloat = brojFloat;
(*novi)->sledeci = NULL; // za sada cvor novi ne pokazuje na sledeci cvor
}
// Kreira listu glava od nizova koji imaju brClanova
void kreiraj_listu_od_nizova ( PCVOR *glava, PCVOR *rep,
char ime[][TEKST_SIZE],
char prezime[][TEKST_SIZE],
int brojInt[],
float brojFloat[],
int brClanova )
{
PCVOR novi; // samo je deklarisan, memorija za njega bice rezervisana u funkciji napravi_novi_cvor()
int i;
for(i=0;i<brClanova;i++){
napravi_novi_cvor( &novi,
ime[i],
prezime[i],
brojInt[i],
brojFloat[i] );
dodaj_na_kraj(glava,rep,novi); // dodajemo na kraj da bi u listi bio isti redosled kao u nizu
}
}
// Brise celu listu glava.
// Funkcija ne zavisi od sadrzaja cvorova liste glava.
void obrisi_celu_listu (PCVOR *glava)
{
PCVOR pom;
while( ( pom = *glava ) != NULL ){ // dok glava postoji, brisemo glavu
pom = *glava; // pocetni cvor glava pamtimo u pom zbog oslobadjanja memorije
*glava = (*glava)->sledeci; // drugi cvor postaje prvi, tj. novi prvi cvor glava postaje njegov (bivsi) sledeci cvor
free(pom); // oslobadjamo memoriju koja je bila rezervisana za pom
} // (tu smo bili zapamtili bivsi prvi cvor glava)
}
// Brise prvi cvor liste glava
// Funkcija ne zavisi od sadrzaja cvorova liste glava.
void obrisi_prvi_cvor (PCVOR *glava){
PCVOR pom;
if( *glava == NULL ){ // ako nema cvorova u listi tj. ako je lista prazna
printf("\n\n Lista je prazna! Nema cvorova za brisanje ! \n\n");
system("PAUSE");
}
else{ // ako ima cvorova u listi tj. ako lista nije prazna
pom = *glava; // pocetni cvor glava pamtimo u pom zbog oslobadjanja memorije
*glava = (*glava)->sledeci; // drugi cvor postaje prvi, tj. novi prvi cvor glava postaje njegov (bivsi) sledeci cvor
free(pom); // oslobadjamo memoriju koja je bila rezervisana za pom
} // (tu smo bili zapamtili bivsi prvi cvor glava)
}
// Brise poslednji cvor liste glava tj. brise rep.
// Funkcija ne zavisi od sadrzaja cvorova liste glava.
void obrisi_poslednji_cvor (PCVOR *glava)
{
PCVOR pom, poslednji; // pomocni cvorovi
poslednji = (PCVOR)malloc(sizeof(CVOR));// rezervisemo memoriju za poslednji, njega na kraju brisemo
if(poslednji == NULL){ // obrada eventualne greske pri rezervisanju memorije
printf("\n Neuspelo rezervisanje memorije. \n");
exit(1);
}
pom = *glava; // glavu pamtimo u cvoru pom (cuvamo glavu da je ne bi promenili)
while( pom->sledeci->sledeci ) // idemo do PRETPOSLEDNJEG cvora !!! CAKA !!!
pom = pom->sledeci; // krecemo se po listi
poslednji = pom->sledeci; // poslednji cvor je sada bivsi pretposlednji cvor
pom->sledeci = NULL; // i on pokazuje na NULL (jer je sada postao poslednji cvor)
free(poslednji); // brisemo bivsi poslednji cvor
}
// Brise sve cvorove ciji je brojInt jednak KojiBrojInt.
void obrisi_sve_cvorove_KojiBrojInt (PCVOR *glava, int KojiBrojInt)
{
PCVOR prethodni=NULL, tekuci=*glava, pom;
while (tekuci != NULL) { // od pocetka do kraja liste
if (tekuci->brojInt == KojiBrojInt) { // ako je to cvor koji ima KojiBrojInt
// KRITERIJUM BRISANJA !
pom = tekuci; // pamtimo tekuci u pom
tekuci = tekuci->sledeci; // prelazimo na na sledeci
// Sta ako brisemo glavu? Kako znamo da je glava: GLAVA NEMA PRETHODNOG !!! CAKA !!!
if( prethodni == NULL ) // ako je tekuci glava
*glava = tekuci; // pamtimo tekuci u glava
else // ako tekuci nije glava
prethodni->sledeci = tekuci; // prethodni pokazuje na tekuceg
free(pom); // brisemo pomocni
}else{ // ako to nije cvor koji ima KojiBrojInt
prethodni = tekuci; // pamtimo prethodni
tekuci = tekuci->sledeci; // prelazimo na na sledeci
}
}
}
// Brise sve cvorove ciji je brojFloat jednak KojiBrojFloat.
void obrisi_sve_cvorove_KojiBrojFloat (PCVOR *glava, float KojiBrojFloat)
{
PCVOR prethodni=NULL, tekuci=*glava, pom;
while (tekuci != NULL) { // od pocetka do kraja liste
if (tekuci->brojFloat == KojiBrojFloat) { // ako je to cvor koji ima KojiBrojFloat
// KRITERIJUM BRISANJA !
pom = tekuci; // pamtimo tekuci u pom
tekuci = tekuci->sledeci; // prelazimo na na sledeci
// Sta ako brisemo glavu? Kako znamo da je glava: GLAVA NEMA PRETHODNOG !!! CAKA !!!
if( prethodni == NULL ) // ako je tekuci glava
*glava = tekuci; // pamtimo tekuci u glava
else // ako tekuci nije glava
prethodni->sledeci = tekuci; // prethodni pokazuje na tekuceg
free(pom); // brisemo pomocni
}else{ // ako to nije cvor koji ima KojiBrojInt
prethodni = tekuci; // pamtimo prethodni
tekuci = tekuci->sledeci; // prelazimo na na sledeci
}
}
}
// Brise sve cvorove ciji je prezime jednako KojePrezime.
void obrisi_sve_cvorove_KojePrezime (PCVOR *glava, char KojePrezime[] )
{
PCVOR prethodni=NULL, tekuci=*glava, pom;
while (tekuci != NULL) { // od pocetka do kraja liste
if ( strcmp(tekuci->prezime, KojePrezime) == 0 ) { // ako je to cvor koji ima KojiBrojFloat
// KRITERIJUM BRISANJA !
pom = tekuci; // pamtimo tekuci u pom
tekuci = tekuci->sledeci; // prelazimo na na sledeci
// Sta ako brisemo glavu? Kako znamo da je glava: GLAVA NEMA PRETHODNOG !!! CAKA !!!
if( prethodni == NULL ) // ako je tekuci glava
*glava = tekuci; // pamtimo tekuci u glava
else // ako tekuci nije glava
prethodni->sledeci = tekuci; // prethodni pokazuje na tekuceg
free(pom); // brisemo pomocni
}else{ // ako to nije cvor koji ima KojiBrojInt
prethodni = tekuci; // pamtimo prethodni
tekuci = tekuci->sledeci; // prelazimo na na sledeci
}
}
}
// U binarnu datoteku ImeDatoteke upisuje listu glava.
// Funkcija ne zavisi od sadrzaja cvorova liste glava.
void upisi_listu_u_bin_datoteku (char ImeDatoteke[],PCVOR glava)
{
FILE *p_fajl;
PCVOR tek = glava; // da glava ne bi bila promenjena, cuvamo glavu
p_fajl = fopen(ImeDatoteke, "wb"); // otvaramo izlaznu binarnu datoteku za pisanje
if( p_fajl == NULL ) { // obrada eventualne greske pri otvaranju fajla
printf("\n Greska pri otvaranju izlaznog bin fajla ! \n");
exit(1); // napustamo program
}
while( tek ){ // od pocetka do kraja liste
// prikazi_jedan_cvor(tek); // prikazuje samo jedan cvor, tek
fwrite(tek, sizeof(CVOR), 1, p_fajl); // ceo jedan cvor tek odjednom upisujemo u datoteku
// Ovde se menja tek (zato nismo radili sa glava) :
tek = tek->sledeci; // idemo na sledeci cvor
}
fclose(p_fajl); // zatvaramo izlaznu bin datoteku
}
// Ucitava listu glava iz binarne datoteke ImeDatoteke.
// Funkcija ne zavisi od sadrzaja cvorova liste glava.
void ucitaj_listu_iz_bin_datoteke (char ImeDatoteke[],PCVOR *glava,PCVOR *rep)
{
FILE *p_fajl;
PCVOR novi; // samo je deklarisan, memorija za njega bice rezervisana kasnije u ovoj funkciji
p_fajl = fopen(ImeDatoteke, "rb"); // otvaramo ulaznu binarnu datoteku za citanje
if( p_fajl == NULL ) { // obrada eventualne greske pri otvaranju fajla
printf("\n Greska pri otvaranju ulaznog bin fajla ! \n");
exit(1); // napustamo program
}
// ucitavamo jedan po jedan cvor liste iz bin datoteke
while( 1 ) { // beskonacna petlja koja se prekida sa break
novi = (PCVOR)malloc(sizeof(CVOR)); // rezervisemo memoriju za cvor novi
if(novi == NULL) { // obrada eventualne greske pri rezervisanju memorije
printf("\n Greska pri rezervisanju memorije! \n");
exit(1); // prekidamo program
}
fread(novi,sizeof(CVOR),1,p_fajl); // u cvor novi ucitavamo ceo jedan cvor iz bin datoteke
// funkciju feof() pozivamo obavezno tek nakon pokusaja citanja sa fread() !
if( feof(p_fajl) ) // ako smo stigli do kraja bin datoteke
break; // prekidamo while petlju
// prikazi_jedan_cvor(novi); // prikazuje samo jedan cvor, novi
dodaj_na_kraj(glava,rep,novi); // dodajemo cvor novi na kraj liste da bi se ocuvao redosled kao u nizovima
}
fclose(p_fajl); // zatvaramo ulaznu bin datoteku
}
// U txt datoteku ImeDatoteke upisuje listu glava.
void upisi_listu_u_txt_datoteku (char ImeDatoteke[],PCVOR glava)
{
FILE *p_fajl;
p_fajl = fopen(ImeDatoteke, "w"); // otvaramo izlaznu txt datoteku za pisanje
if( p_fajl == NULL ) { // obrada eventualne greske pri otvaranju fajla
printf("\n Greska pri otvaranju izlaznog txt fajla ! \n");
exit(1);
}
while(glava){ // od pocetka do kraja liste glava
// fprintf(u sta, format, sta)
// fprintf() vraca broj upisanih elemenata. Ako je greska, vraca negativan broj.
// Upis mora u ovom formatu, ne moze sa %-6s ili sa %6.2f !!!
fprintf(p_fajl, "%6s %8s %5d %f \n",
glava->ime,
glava->prezime,
glava->brojInt, // nema potrebe da upisujemo pokazivac na sledeci cvor
glava->brojFloat ); // jer ce se on biti formiran pri dodavanju cvora u listu
// ovde se glava menja, ali nije preneta kao pointer tako da ne treba da je cuvamo u cvoru pom
glava = glava->sledeci; // idemo na sledeci cvor
}
fclose(p_fajl); // zatvaramo izlaznu txt datoteku
}
// Iz txt datoteke ImeDatoteke ucitava listu glava.
void ucitaj_listu_iz_txt_datoteke(char ImeDatoteke[],PCVOR *glava,PCVOR *rep)
{
FILE *p_fajl; // deklaracija pointera na fajl
PCVOR novi; // samo je deklarisan, memorija za njega bice kasnije rezervisana u petlji while
p_fajl = fopen(ImeDatoteke, "r"); // otvaramo ulaznu txt datoteku za citanje
if( p_fajl == NULL ) { // obrada eventualne greske pri otvaranju fajla
printf("\n Greska pri otvaranju ulaznog txt fajla %s ! \n", ImeDatoteke);
exit(1);
}
// fscanf(odakle, format, adrese u sta),
// fscanf() vraca broj ucitanih elemenata ili EOF na kraju fajla.
// Ucitavamo jedan po jedan red iz txt fajla U ISTOM FORMATU u kojem smo je upisali u txt fajl:
while ( 1 ) { // beskonacna petlja koja se prekida sa break
novi = (PCVOR)malloc(sizeof(CVOR)); // rezervisemo memoriju za cvor novi
if(novi == NULL) { // obrada eventualne greske pri rezervisanju memorije
printf("\n Greska pri rezervisanju memorije! \n");
exit(1); // izlazimo iz programa
}
// Ucitavamo jedan red iz ulaznog txt fajla U ISTOM FORMATU u kojem je upisan u txt fajl:
fscanf(p_fajl, "%6s %8s %5d %f \n",
novi->ime, // NE TREBA & (ADRESA) !!!
novi->prezime, // NE TREBA & (ADRESA) !!!
&(novi->brojInt),
&(novi->brojFloat) );
novi->sledeci = NULL; // za sada, za svaki slucaj
// prikazi_jedan_cvor(novi); // prikazuje samo jedan cvor, novi
dodaj_na_kraj(glava,rep,novi); // dodajemo cvor novi na kraj liste da bi se ocuvao redosled kao u nizovima
if (feof(p_fajl)) // Ukoliko smo dosli do kraja datoteke, prekidamo while(1) petlju
break;
}
fclose(p_fajl); // zatvaramo ulaznu txt datoteku
}
// Medjusobno zamenjuje sadrzaje dva cvora i,j.
// To je pomocna funkcija za sortiranje liste tehnikom medjusobnog premestanja
// putnika dva vagona, dok vagoni ostaju na svojim mestima (to se vidi po adresama sledeceg).
// Lista je kao kompozicija voza. Na pocetku (glava) je lokomotiva,
// a iza nje su vagoni i svi su povezani (pointer na sledeci).
// Elementi liste su kao putnici u vagonima voza.
// Kada sortiramo, odnosno premestamo radi sortiranja,
// ne moramo da premestamo vagone, neka oni ostanu na svojim mestima.
// Samo premestamo putnike iz jednog vagona u drugi.
// Na taj nacin nema potrebe da menjamo pokazivace na sledece vagone,
// jer raspored vagona ostaje isti, samo su se putnici (sadrzaj cvora) premestili.
void zameni_medjusobno_sadrzaje_cvorova( PCVOR *i, PCVOR *j)
{ // argumenti su pointeri jer funkcija menja cvorove i,j.
// char* mem_s=(char*)malloc(sizeof(char)*TEKST_SIZE); // moze i tako, sa malloc()
// char* mem_int=(int*)malloc(sizeof(int));
// char* mem_float=(float*)malloc(sizeof(float));
char mem_s[TEKST_SIZE]; // pomocna memorija za sortiranje string podataka
int mem_int; // pomocna memorija za sortiranje int podataka
float mem_float; // pomocna memorija za sortiranje float podataka
// Sledi deo funkcije zavisi od sadrzaja cvorova:
strcpy( mem_s, (*i)->ime ); // za stringove mora strcpy()
strcpy( (*i)->ime, (*j)->ime );
strcpy( (*j)->ime, mem_s );
strcpy( mem_s, (*i)->prezime );
strcpy( (*i)->prezime, (*j)->prezime );
strcpy( (*j)->prezime, mem_s );
mem_int = (*i)->brojInt;
(*i)->brojInt = (*j)->brojInt;
(*j)->brojInt = mem_int;
mem_float = (*i)->brojFloat;
(*i)->brojFloat = (*j)->brojFloat;
(*j)->brojFloat = mem_float;
}
// Sortira neopadajuce listu glava neopadajuce po imenima premestanjem sadrzaja cvorova.
// strcmp(a,b) uporedjuje stringove a i b i vraca: ( CoMPare )
// -1 za a<b
// 0 za a=b
// 1 za a>b
void sortiraj_listu_neopadajuce_po_ime(PCVOR *glava)
{
PCVOR i,j; // pomocni cvorovi za sortiranje
for(i=*glava;i;i=i->sledeci) // od prvog do poslednjeg cvora (tada je i = NULL)
for(j=*glava;j;j=j->sledeci) // od prvog do poslednjeg cvora (tada je j = NULL)
if( strcmp(i->ime, j->ime) == -1 ) // KRITERIJUM SORTIRANJA !
// == 1 za nerastuci (obrnuti) redosled sortiranja
// MORAMO MEDJUSOBNO ZAMENITI SVE SADRZAJE CVOROVA (putnike vagona) i,j
zameni_medjusobno_sadrzaje_cvorova( &i, &j );
// predajemo adrese jer funkcija menja cvorove
}
// Sortira neopadajuce listu glava po prezimenima
// strcmp(a,b) uporedjuje stringove a i b i vraca: ( CoMPare )
// -1 za a<b
// 0 za a=b
// 1 za a>b
void sortiraj_listu_neopadajuce_po_prezime(PCVOR *glava)
{
PCVOR i,j; // pomocni cvorovi za sortiranje
for(i=*glava;i;i=i->sledeci) // od prvog do poslednjeg cvora (tada je i = NULL)
for(j=*glava;j;j=j->sledeci) // od prvog do poslednjeg cvora (tada je j = NULL)
if( strcmp(i->prezime, j->prezime) == -1 ) // KRITERIJUM SORTIRANJA !
// == 1 za nerastuci (obrnuti) redosled sortiranja
// MORAMO MEDJUSOBNO ZAMENITI SVE SADRZAJE CVOROVA (putnike vagona) i,j
zameni_medjusobno_sadrzaje_cvorova( &i, &j );
// predajemo adrese jer funkcija menja cvorove
}
// Sortira neopadajuce listu glava po brojInt
void sortiraj_listu_neopadajuce_po_brojInt(PCVOR *glava)
{
PCVOR i,j; // pomocni cvorovi za sortiranje
for(i=*glava;i;i=i->sledeci) // od prvog do poslednjeg cvora (tada je i = NULL)
for(j=*glava;j;j=j->sledeci) // od prvog do poslednjeg cvora (tada je j = NULL)
if( i->brojInt < j->brojInt ) // KRITERIJUM SORTIRANJA !
// > za nerastuci (obrnuti) redosled sortiranja
// MORAMO MEDJUSOBNO ZAMENITI SVE SADRZAJE CVOROVA (putnike vagona) i,j
zameni_medjusobno_sadrzaje_cvorova( &i, &j );
// predajemo adrese jer funkcija menja cvorove
}
// Sortira neopadajuce listu glava po brojFloat
void sortiraj_listu_neopadajuce_po_brojFloat(PCVOR *glava)
{
PCVOR i,j; // pomocni cvorovi za sortiranje
for(i=*glava;i;i=i->sledeci) // od prvog do poslednjeg cvora (tada je i = NULL)
for(j=*glava;j;j=j->sledeci) // od prvog do poslednjeg cvora (tada je j = NULL)
if( i->brojFloat < j->brojFloat ) // KRITERIJUM SORTIRANJA !
// > za nerastuci (obrnuti) redosled sortiranja
// MORAMO MEDJUSOBNO ZAMENITI SVE SADRZAJE CVOROVA (putnike vagona) i,j
zameni_medjusobno_sadrzaje_cvorova( &i, &j );
// predajemo adrese jer funkcija menja cvorove
}
/*
Sortiranje liste premestanjem cvorova u neopadajuci redosled,
( od sadrzaja cvorova zavisi samo u KRITERIJUMU ZA SORTIRANJE ) :
Da bismo sortirali listu p, prvo prolazimo kroz nju kako bismo pronasli
element sa najvecom vrednoscu podatka.
Nakon toga uklanjamo taj element iz liste p
i dodajemo ga na pocetak druge liste nova_glava, koja je inicijalno bila prazna.
Ovaj proces ponavljamo sve dok pocetna lista p ne postane prazna.
Na kraju p postaje pokazivac na listu nova_glava u koju su prebaceni svi elementi.
*/
// Sortira listu premestanjem cvorova u neopadajuci redosled,
// ( od sadrzaja cvorova zavisi samo u KRITERIJUMU ZA SORTIRANJE )
void sortiraj_listu_premestanjem_cvorova_neopadajuce_po_prezime( PCVOR *glava )
{
PCVOR tekuci, tek_sledeci, max, prethodni, nova_glava;
nova_glava = NULL;
while( *glava ){ // do kraja liste
prethodni = NULL;
max = *glava; // pretpostavljamo da je najveci bas prvi element (glava)
tekuci = *glava;
tek_sledeci = (*glava)->sledeci;
while ( tek_sledeci ) {
// ---------------------------------------------------------------------------------------------
// KRITERIJUM SORTIRANJA, SAMO TU FUNKCIJA ZAVISI OD SADRZAJA CVOROVA
// ->ime ->ime
// if( strcmp( max->ime , tek_sledeci->ime ) == 1 )
// ->prezime ->prezime
if( strcmp( max->prezime , tek_sledeci->prezime ) == 1 )
// ->brojInt ->brojInt
// if( max->brojInt > tek_sledeci->brojInt )
// ->brojFloat ->brojFloat
// if( max->brojFloat > tek_sledeci->brojFloat )
// I SAMO TU JE TREBA PRILAGODITI SADRZAJU CVOROVA
// I REDOSLEDU SORTIRANJA ( == -1 odnosno < za nerastuci redosled )
// ---------------------------------------------------------------------------------------------
{
max = tek_sledeci; // max postaje tek_sledeci
prethodni = tekuci;
}
tekuci = tek_sledeci;
tek_sledeci = tek_sledeci->sledeci;
}
if( prethodni == NULL )
*glava = max->sledeci;
else
prethodni->sledeci = max->sledeci;
max->sledeci = NULL;
// dodaj max na kraj nova_glava (bez repa)
if( nova_glava == NULL )
nova_glava = max; // premesta element sa najvecom vrednoscu podatka iz liste glava na pocetak liste nova_glava
else {
tekuci = nova_glava;
// prolazi kroz listu nova_glava da bi pronasao njen poslednji element
while( tekuci->sledeci )
tekuci = tekuci->sledeci;
// premesta element sa najvecom vrednoscu podatka iz liste glava na kraj liste nova_glava
tekuci->sledeci = max;
}
}
// glava postaje nova_glava
*glava = nova_glava; // Na kraju glava postaje pokazivac na listu nova_glava u koju su prebaceni svi elementi.
}
int main (void)
{
char ime[MAX_SIZE][TEKST_SIZE] = {"Ivana","Pera","Mika","Laza"}; // niz imena
char prezime[MAX_SIZE][TEKST_SIZE] = {"Milicev","Peric","Mikic","Lazic"}; // niz prezimena
int nizInt[MAX_SIZE] = {1997, 1992, 1996, 1995}; // niz integer-a
float nizFloat[MAX_SIZE] = {9.78, 8.45, 7.56, 10.0}; // niz float-a
int brClanova = 4; // broj clanova nizova stringova, integer-a i float-a
PCVOR Lista = NULL; // lista
PCVOR rep = NULL; // rep liste
printf("\n sizeof(CVOR) = %2d \n",sizeof(CVOR)); // prikaz velicine memorije za CVOR
printf("\n sizeof(PCVOR) = %2d \n",sizeof(PCVOR)); // prikaz velicine memorije za PCVOR
// Kreiramo listu od nizova stringova, integer-a i float-a.
// Dajemo adresu jer se vrsi promena liste.
kreiraj_listu_od_nizova( &Lista, &rep,
ime,
prezime,
nizInt,
nizFloat,
brClanova );
// prikazujemo listu kreiranu od nizova, ne treba adresa jer se lista samo cita
prikazi_listu("Lista iz nizova je: ",Lista);
// Binarna datoteka:
// Listu upisujemo u bin datoteku, ne treba adresa jer se lista samo cita
printf("\n\n Listu upisujemo u bin datoteku. \n");
upisi_listu_u_bin_datoteku("Lista.bin",Lista);
// Brisemo celu listu, dajemo adresu jer se vrsi promena liste
printf("\n\n Brisemo celu listu (upisana je u bin datoteku). \n");
obrisi_celu_listu(&Lista);
prikazi_listu("Lista nakon brisanja je: ",Lista);
// Listu ucitavamo iz bin datoteke, dajemo adrese jer se vrsi promena liste
printf("\n\n Listu ucitavamo iz bin datoteke. \n");
ucitaj_listu_iz_bin_datoteke("Lista.bin",&Lista,&rep);
// prikazujemo listu ucitanu iz bin datoteke, ne treba adresa jer se lista samo cita
prikazi_listu("Lista iz bin datoteke je: ",Lista);
// Tekstualna datoteka:
// Listu upisujemo u txt datoteku, ne treba adresa jer se lista samo cita
printf("\n\n Listu upisujemo u txt datoteku. \n");
upisi_listu_u_txt_datoteku("Lista.txt",Lista);
// Brisemo celu listu, dajemo adresu jer se vrsi promena liste
printf("\n\n Brisemo celu listu (upisana je u txt datoteku). \n");
obrisi_celu_listu(&Lista);
prikazi_listu("Lista nakon brisanja je: ",Lista);
// Listu ucitavamo iz txt datoteke, dajemo adrese jer se vrsi promena liste
printf("\n\n Listu ucitavamo iz txt datoteke. \n");
ucitaj_listu_iz_txt_datoteke("Lista.txt",&Lista,&rep);
// prikazujemo listu ucitanu iz txt datoteke, ne treba adresa jer se lista samo cita
prikazi_listu("Lista iz txt datoteke je: ",Lista);
// Sortiranja liste
printf("\n\n\n Sortiranja liste: \n");
// Sortiramo listu neopadajuce po imenima
sortiraj_listu_neopadajuce_po_ime(&Lista);
prikazi_listu("Lista sortirana neopadajuce po imenima je: ",Lista);
// Sortiramo listu neopadajuce po prezimenima
sortiraj_listu_neopadajuce_po_prezime(&Lista);
prikazi_listu("Lista sortirana neopadajuce po prezimenima je: ",Lista);
// Sortiramo listu neopadajuce po brojInt
sortiraj_listu_neopadajuce_po_brojInt(&Lista);
prikazi_listu("Lista sortirana neopadajuce po brojInt je: ",Lista);
// Sortiramo listu neopadajuce po brojFloat
sortiraj_listu_neopadajuce_po_brojFloat(&Lista);
prikazi_listu("Lista sortirana neopadajuce po brojFloat je: ",Lista);
// Sortiramo listu premestanjem cvorova neopadajuce po prezimenima
sortiraj_listu_premestanjem_cvorova_neopadajuce_po_prezime(&Lista);
prikazi_listu("Lista sortirana premestanjem cvorova neopadajuce po prezimenima je: ",Lista);
/*
// brisanje napravljenih datoteka
remove("Lista.txt");
remove("Lista.bin");
*/
printf("\n\n\n");
system("PAUSE");
return 0;
}