/* Implementacija skupa pomocu povezane liste */ #include /* calloc */ #include /* NULL */ #include /* Zbog assert funkcije */ #include "collection.h" /* Ucitaj specifikaciju */ extern void *ItemKey( void * ); struct t_node { void *item; struct t_node *next; } node; struct t_Collection { int size; /* Potrebno za FindInCollection metod */ struct t_node *node; }; Collection ConsCollection(int max_items, int item_size ) /* Kreiraj novi skup Pre-uslov: (max_items > 0) && (item_size > 0) Post-uslov: vraca pointer na prazan skup */ { Collection c; /* Iako nepotrebna, ovu proveru treba zadrzati jer proverava saglasnost sa formalnom specifikacijom */ assert( max_items > 0 ); assert( item_size > 0 ); c = (Collection)calloc( 1, sizeof(struct t_Collection) ); c->node = (struct t_node *)0; c->size = item_size; return c; } void AddToCollection( Collection c, void *item ) /* Dodaje objekat u skup Pre-uslov: (c je skup kreiran pozivom ConsCollection) && (postojeci broj objekata < max_items) && (item != NULL) Post-uslov: objekat je dodat u skup c */ { struct t_node *new; assert( c != NULL ); assert( item != NULL ); /* alociraj memoriju za cvor novog objekta */ new = (struct t_node *)malloc(sizeof(struct t_node)); /* prekopiraj objekat u cvor */ new->item = item; /* neka postojeca lista `visi' sa ovog cvora */ new->next = c->node; /* novi objekat je nova glava liste */ c->node = new; assert( FindInCollection( c, ItemKey( item ) ) != NULL ); } void DeleteFromCollection( Collection c, void *item ) /* Brise objekat iz skupa Pre-uslov: (c je skup kreiran pozivom ConsCollection) && (postojeci broj objekata >= 1) && (item != NULL) Post-uslov: objekat je obrisan iz skupa c */ { struct t_node *node, *prev; assert( c != NULL ); /* Zahtev da skup ima bar jedan element se proverava malo drugacije */ assert( c->node != NULL ); assert( item != NULL); /* izaberi cvor na glavi liste */ prev = node = c->node; /* sve dok ne stignemo do kraja liste... */ while( node != NULL ) { if ( item == node->item ) { /* Pronadjen objekat koji treba obrisati, prepovezi listu tako da ga zaobilazi */ if( node == c->node ) /* Brisemo glavu */ c->node = node->next; else prev->next = node->next; /* Oslobodi cvor */ free( node ); break; } prev = node; node = node->next; } } void *FindInCollection( Collection c, void *key ) /* Trazi objekat u skupu Pre-condition: (c je skup kreiran pozivom ConsCollection) && (key != NULL) Post-uslov: vraca objekat identifikovan kljucem key ako takav postoji, u suprotnom vraca NULL */ { struct t_node *node; assert( c != NULL ); assert( key != NULL ); /* Pocni sa glavom liste */ node = c->node; while( node != NULL) { if ( memcmp(key,ItemKey(node->item),c->size)==0 ) { return node->item; } node = node->next; } return NULL; }