diff --git a/example1.c b/example1.c index 2bfeeed..b620192 100644 --- a/example1.c +++ b/example1.c @@ -1,148 +1,253 @@ -/*/*/* /*/*/* /*/*/* /*/*/* /*/*/* /*/*/* /*/*/* /*/*/* /*/*/* /*/*/* /*/*/* /*Determinati daca exista sau nu drum direct intre doua restaurante dintr-o retea de tip graf*/ - - #include - #include - - typedef struct Node{ - int data; - struct Node *next;} - /// pentru simplitate, folosim int uri pt a numi restaurantel/locatiile - /// ex: 1 - restaurantul 1 si tot asa - - NODE; - - - typedef struct g - { - int v; - int *vis; - struct Node **alst; - } - GPH; - - typedef struct s{int t;int scap;int *arr;} STK; - - NODE *create_node(int v){ - NODE *nn=malloc(sizeof(NODE)); - nn->data=v; - nn->next=NULL; - return nn;} - - void add_edge(GPH *g,int src,int dest) - { - NODE *nn=create_node(dest); - nn->next=g->alst[src]; - g->alst[src]=nn; - nn=create_node(src); - nn->next=g->alst[dest]; - g->alst[dest]=nn; - } - - GPH *create_g(int v) - { - int i; - GPH *g=malloc(sizeof(GPH)); - g->v=v; - g->alst=malloc(sizeof(NODE *)); - g->vis=malloc(sizeof(int) *v); - - for (int i=0;ialst[i]=NULL; - g->vis[i]=0; - }/*/*/* - return g; - } - - STK *create_s(int scap) - { - STK *s=malloc(sizeof(STK)); - s->arr=malloc(scap*sizeof(int)); - s->t = -1; - s->scap=scap; - - return s; - } - - void push(int pshd,STK *s) - { - s->t=s->t+1; - s->arr[s->t]=pshd; - } - - void DFS(GPH *g,STK *s,int v_nr) - { - N0DE *adj_list=g->alst[v_nr]; - NODE *aux=adj_list; - g->vis[v_nr]=1; - printf("%d ",v_nr); - push(v_nr,s); - while (aux != NULL){ - int con_ver=aux->data;if (g->vis[con_ver]==0) - DFS(*g,*s,*con_ver); - aux=aux->next; - } - } - - void insert_edges(GPH *g,int edg_nr,int nrv) - { - int src,dest,i; - printf("adauga %d munchii (de la 1 la %d)\n",edg_nr,nrv); - for (i=0;ivis[i] = 0; - } - }/*/*/* - - void canbe(GPH *g, int nrv, STK *s1, STK *s2)// 0 sau 1 daca poate fi sau nu ajuns - { - int *canbe = calloc(5, sizeof(int)); - for (int i = 0; i < nrv; i++) // aici i tine loc de numar adica de restaurant{for (int j = 0; j < 5; j++) - { - DFS(g, s1, i); - wipe(g, nrv); - DFS(g, s2, j); - for (int j = 0; j < nrv && !ans; j++) - for (int i = 0; i < nrv && !ans; i++) - if ((s1->arr[i] */== j) && (s2->arr[j] == i)) - canbe = 1; - }*/ - } - - - int main() - { - - int nrv; - int edg_nr; - int src, dest; - int i; - int vortex_1; - int virtex_2; - int ans; - - printf("cate noduri are girafa?"); - scanf("%d", &nrv); - - printf("cate muchii are giraful?"); - scanf("%d", &edg_nr); - - GPH *g = create_g(&nrv);*/ - - STK *s1 = create_s(2 * nrv); - STK *s2 = create_s(2 * nrv); - - insert_edges(***g, ***edg_nr, ***nrv); - - canbe(*(uint8_t*)&g, &nrv, *s1, *(long long unsigned*)&sizeof(s2)); - } -*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ \ No newline at end of file +#include +#include + +typedef struct Restaurant +{ + int id_restaurant; + struct Restaurant *urmator; +} RESTAURANT; + +typedef struct Graf +{ + int nr_noduri; + int *vizitat; + struct RESTAURANT **legatura; +} GRAF; + +typedef struct Stiva +{ + int top; + int capacitate; + int *elemente; +} STIVA; + +RESTAURANT *creareNod(int id_restaurant) +{ + RESTAURANT *nod = malloc(sizeof(RESTAURANT)); + nod->id_restaurant = id_restaurant; + nod->urmator = NULL; + return nod; +} + +void adaugaDrum(GRAF *graf, int restaurant1, int restaurant2) +{ + //Cream un nod pentru restaurantul2 si il adaugam in lista de adiacenta a restaurantului1 + RESTAURANT *nod = creareNod(restaurant2); + nod->urmator = graf->legatura[restaurant1]; //Legam restaurantul1 de restaurantul2 + graf->legatura[restaurant1] = nod; + + //Cream un nod pentru restaurantul1 si il adaugam in lista de adiacenta a restaurantului2 + nod = creareNod(restaurant1); + nod->urmator = graf->legatura[restaurant2]; //Legam restaurantul2 de restaurantul1 + graf->legatura[restaurant2] = nod; +} + +GRAF *creareGraf(int nr_noduri) +{ + GRAF *graf = malloc(sizeof(GRAF)); + + if(graf == NULL) + { + printf("Eroare la alocarea dinamica."); + exit(1); + } + + graf->nr_noduri = nr_noduri; + graf->legatura = malloc(sizeof(RESTAURANT *) * nr_noduri); + + if(graf->legatura == NULL) + { + printf("Eroare la alocarea dinamica."); + exit(1); + } + + graf->vizitat = malloc(sizeof(int) * nr_noduri); + + if(graf->vizitat == NULL) + { + printf("Eroare la alocarea dinamica."); + exit(1); + } + + for (int i = 0; i < nr_noduri; i++) + { + graf->legatura[i] = NULL; + graf->vizitat[i] = 0; + } + return graf; +} + +STIVA *creareStiva(int capacitate) +{ + STIVA *stiva = malloc(sizeof(STIVA)); + + if(stiva == NULL) + { + printf("Eroare la alocarea dinamica."); + exit(1); + } + + stiva->elemente = malloc(capacitate * sizeof(int)); + + if(stiva->elemente == NULL) + { + printf("Eroare la alocarea dinamica."); + exit(1); + } + + stiva->top = -1; + stiva->capacitate = capacitate; + return stiva; +} + +void push(STIVA *stiva, int valoare) +{ + stiva->top = stiva->top + 1; + stiva->elemente[stiva->top] = valoare; +} + +//DFS (Depth First Search)- exploreaza graful in adancime +void dfs(GRAF *graf, STIVA *stiva, int varf) +{ + RESTAURANT *vecin = graf->legatura[varf]; //Obtinem lista de vecini a restaurantului curent + + graf->vizitat[varf] = 1; //Marcam restaurantul curent ca vizitat + push(stiva, varf); //Adaugam restaurantul in stiva + + while (vecin != NULL) + { + int id = vecin->id_restaurant; + if (graf->vizitat[id] == 0) //Daca vecinul nu a fost vizitat + { + dfs(graf, stiva, id); //Apelam recursiv dfs pentru vecin + } + vecin = vecin->urmator; + } +} + +void citesteDrum(GRAF *graf, int nr_drumuri) +{ + int restaurant1, restaurant2, i; + printf("Adauga %d muchii (de la 1 la %d)\n", nr_drumuri, graf->nr_noduri); + + for (i = 0; i < nr_drumuri; i++) + { + do + { + scanf("%d %d", &restaurant1, &restaurant2); + + if(restaurant1 < 1 || restaurant1 > graf->nr_noduri || restaurant2 < 1 || restaurant2 > graf->nr_noduri) + printf("Numar invalid de restaurant.\n"); + } + while (restaurant1 < 1 || restaurant1 > graf->nr_noduri || restaurant2 < 1 || restaurant2 > graf->nr_noduri); + + adaugaDrum(graf, restaurant1 - 1, restaurant2 - 1); + } +} + +//Reseteaza statusul de vizitare al tuturor restaurantelor +void resetareVizitare(GRAF *graf, int nr_restaurante) +{ + for (int i = 0; i < nr_restaurante; i++) + { + graf->vizitat[i] = 0; + } +} + +int existaDrum(GRAF *graf, int nr_restaurante, STIVA *restaurant_start, STIVA *restaurant_destinatie) +{ + int restaurant1, restaurant2; + + printf("Introdu doua restaurante (de la 1 la %d): ", nr_restaurante); + scanf("%d %d", &restaurant1, &restaurant2); + + if(restaurant1 < 1 || restaurant1 > nr_restaurante || restaurant2 < 1 || restaurant2 > nr_restaurante) + { + printf("Numar invalid de restaurante.\n"); + return 0; + } + + restaurant_start->top = -1; + restaurant_destinatie->top = -1; + + dfs(graf, restaurant_start, restaurant1 - 1); + resetareVizitare(graf, nr_restaurante); + dfs(graf, restaurant_destinatie, restaurant2 - 1); + + // Verificam daca exista un nod comun intre cele doua stive + for (int i = 0; i <= restaurant_start->top; i++) + { + for (int j = 0; j <= restaurant_destinatie->top; j++) + { + if (restaurant_start->elemente[i] == restaurant_destinatie->elemente[j]) + { + return 1; // Exista drum + } + } + } + return 0; // Nu exista drum +} + +int main() +{ + int nr_restaurante, nr_drumuri; + + printf("Cate noduri (restaurante) are graful? "); + scanf("%d", &nr_restaurante); + + if(nr_restaurante < 1) + { + printf("Numar invalid de restaurante.\n"); + return 1; + } + + printf("Cate muchii (drumuri) are graful? "); + scanf("%d", &nr_drumuri); + + GRAF *graf = creareGraf(nr_restaurante); + citesteDrum(graf, nr_drumuri); + + //Cream 2 stive pentru a pastra traseele + STIVA *restaurant_start = creareStiva(2 * nr_restaurante); + STIVA *restaurant_destinatie = creareStiva(2 * nr_restaurante); + + printf("Ordinea nodurilor vizitate in DFS: "); + dfs(graf, restaurant_start, 0); + + for (int i = 0; i <= restaurant_start->top; i++) + { + printf("%d ", restaurant_start->elemente[i] + 1); + } + printf("\n"); + + int exista = existaDrum(graf, nr_restaurante, restaurant_start, restaurant_destinatie); + if (exista) + { + printf("Exista drum intre cele doua restaurante.\n"); + } + else + { + printf("Nu exista drum intre cele doua restaurante.\n"); + } + + free(graf->vizitat); + for (int i = 0; i < nr_restaurante; i++) + { + RESTAURANT *curent = graf->legatura[i]; + while (curent != NULL) + { + RESTAURANT *temp = curent; + curent = curent->urmator; + free(temp); + } + } + free(graf->legatura); + free(graf); + + free(restaurant_start->elemente); + free(restaurant_start); + free(restaurant_destinatie->elemente); + free(restaurant_destinatie); + + return 0; +} diff --git a/example2.c b/example2.c index 0e67b95..b194680 100644 --- a/example2.c +++ b/example2.c @@ -3,174 +3,253 @@ //Imi cer scuze in avans #include - #include -typedef struct Node + +typedef struct Nod { -int data; -struct Node *next; -} NODE; -typedef struct Graph{ int vertices;int *visited;struct Node **adjacency_lists;} GPH; + int valoare; + struct Nod *urmator; +} NOD; + +typedef struct Graf +{ + int varfuri; + int *vizitat; + struct NOD **liste_adiacenta; +} GRAF; + /// utils - NODE *create_node(int v){ NODE *new_node = malloc(sizeof(NODE)); new_node->data = v; new_node->next = NULL;return new_node;} -GPH *create_graph(int vertices) +NOD *creareNod(int v) +{ + NOD *nod_nou = malloc(sizeof(NOD)); + + if (nod_nou == NULL) + { + printf("Eroare la alocarea dinamica."); + exit(1); + } + + nod_nou->valoare = v; + nod_nou->urmator = NULL; + return nod_nou; +} + +GRAF *creareGraf(int varfuri) { int i; - GPH *graph = malloc(sizeof(GPH)); - graph->vertices = vertices;graph->adjacency_lists = malloc(vertices * sizeof(NODE *)); + GRAF *graf = malloc(sizeof(GRAF)); + if (graf == NULL) + { + printf("Eroare la alocarea dinamica."); + exit(1); + } + graf->varfuri = varfuri; + graf->liste_adiacenta = malloc(varfuri * sizeof(NOD *)); + if (graf->liste_adiacenta == NULL) + { + printf("Eroare la alocarea dinamica."); + exit(1); + } - graph->visited = malloc(sizeof(int) * vertices); - for (int i = 0; i < vertices; i++) + graf->vizitat = malloc(sizeof(int) * varfuri); + if (graf->vizitat == NULL) { - graph->adjacency_lists[i] = NULL; - graph->visited[i] = 0; - } return graph; + printf("Eroare la alocarea dinamica."); + exit(1); + } + + for (int i = 0; i < varfuri; i++) + { + graf->liste_adiacenta[i] = NULL; + graf->vizitat[i] = 0; + } + + return graf; } -void add_edge(GPH *graph, int src, int dest) -{ - NODE *new_node = create_node(dest); - new_node->next = graph->adjacency_lists[src]; - graph->adjacency_lists[src] = new_node; +void adaugaMuchie(GRAF *graf, int sursa, int destinatie) +{ + NOD *nod_nou = creareNod(destinatie); + nod_nou->urmator = graf->liste_adiacenta[sursa]; // Adauga nodul 'destinatie' in lista de adiacenta a nodului 'sursa' + graf->liste_adiacenta[sursa] = nod_nou; // Adauga nodul 'sursa' in lista de adiacenta a nodului 'destinatie' - new_node = create_node(src); + nod_nou = creareNod(sursa); + nod_nou->urmator = graf->liste_adiacenta[destinatie]; + graf->liste_adiacenta[destinatie] = nod_nou; +} - new_node->next = graph->adjacency_lists[dest]; - graph->adjacency_lists[dest] = new_node; +void citireMuchie(int nr_noduri, int nr_muchii, GRAF *graf) +{ + int sursa, destinatie, i; + printf("Adauga %d muchii (de la 1 la %d)\n", nr_muchii, nr_noduri-1); + for (i = 0; i < nr_muchii; i++) + { + scanf("%d%d", &sursa, &destinatie); + sursa--; + destinatie--; + adaugaMuchie(graf, sursa, destinatie); + } } -int *insedg(int nr_of_vertices, int nr_of_edges, GPH *graph){ int src, dest, i; printf("adauga %d muchii (de la 1 la %d)\n", nr_of_edges, nr_of_vertices); - for (i = 0; i < nr_of_edges; i++){scanf("%d%d", &src, *&dest);add_edge(graph, src, dest);}} + /// bfs utils -int is_empty(NODE *queue) +int esteGol(NOD *coada) { - return - queue == NULL; + return coada == NULL; } +void adaugaInCoada(NOD **coada, int valoare) +{ + NOD *nod_nou = creareNod(valoare); + if (esteGol(*coada)) { + *coada = nod_nou; + } + else + { + NOD *temp = *coada; + while (temp->urmator) + { + temp = temp->urmator; + } + temp->urmator = nod_nou; + } +} - - - - -void enqueue(NODE ***queue, int data) +int stergeDinCoada(NOD **coada) { - NODE *new_node = create_node(data); + int valoare = (*coada)->valoare; + NOD *temp = *coada; + *coada = (*coada)->urmator; + return valoare; +} - if (is_empty(*queue)) *queue = new_node; -else +void afisareGraf(GRAF *graf) { - NODE *temp = *queue; - while (temp->next) - {temp = temp->next;}temp->next = new_node;}} - -int dequeue(NODE -**queue) -{ int data = (*queue)->data;NODE *temp = *queue;*queue = (*queue)->next;return data; + int i; + for (i = 0; i < graf->varfuri; i++) + { + NOD *temp = graf->liste_adiacenta[i]; + + while (temp) + { + printf("%d ", temp->valoare); + temp = temp->urmator; + } + printf("\n"); + } } -void print_graph(GPH *graph) +void afisareCoada(NOD *coada) { - int i; for (i = 0; i < graph->vertices; (i<<2) += 1) + while (coada != NULL) { - NODE *temp = graph->adjacency_lists[i<<2]; - - while (temp) { - printf("%d ", temp->data); - temp = *(temp->next)->data; - }printf("\n"); + printf("%d ", coada->valoare); + coada = coada->urmator; } } -void print_queue(NODE *queue) +// Reseteaza lista de noduri vizitate pentru a permite o noua parcurgere +void resetareVizitare(GRAF *graf, int nr_noduri) { -while (queue != NULL) -{printf("%d ", queue->data);queue = *(queue->next)->next;}} - + for (int i = 0; i < nr_noduri; i++) + { + graf->vizitat[i] = 0; // Resetam fiecare nod la 0 (nevizitat) + } +} -void wipe_visited_list(GPH *graph, int nr_of_vertices) -{ -for (int i = 0; -i < nr_of_vertices; - i++) +// Parcurgeri +// Parcurge graful folosind DFS (Depth First Search) +void dfs(GRAF *graf, int nod_nr) { -graph->visited[i] = 0;}} -// parcurgeri -void DFS(GPH *graph, int vertex_nr) -{ - NODE *adj_list = graph->adjacency_lists[vertex_nr]; -NODE *temp = adj_list; + NOD *adj_list = graf->liste_adiacenta[nod_nr]; + NOD *temp = adj_list; -graph->visited[vertex_nr] = 1; -printf("%d->", vertex_nr); + if (nod_nr < 0 || nod_nr >= graf->varfuri) { + return; + } -while (temp != NULL) -{ - int connected_vertex = temp->data; + graf->vizitat[nod_nr] = 1; // Marcheaza nodul curent ca vizitat + printf("%d->", nod_nr + 1); - if (graph->visited[connected_vertex] == 0) + while (temp != NULL) { - DFS(graph, connected_vertex); -} -temp = temp->next; -} + + int vecin = temp->valoare; + + // Daca nodul nu a fost vizitat inca, il parcurgem recursiv + if (graf->vizitat[vecin] == 0) + { + dfs(graf, vecin); + } + temp = temp->urmator; + } } -void BFS(GPH *graph, int start) +// Parcurge graful folosind BFS (Breadth First Search) +// Coada este utilizata pentru a parcurge nivel cu nivel nodurile grafului +void bfs(GRAF *graf, int start) { -NODE *queue = NULL; + NOD *coada = NULL; -graph->visited[start] = 1; -enqueue(&queue, start); + graf->vizitat[start] = 1; + adaugaInCoada(&coada, start); - while (!is_empty(queue)) + while (!esteGol(coada)) { -int current = dequeue(&queue); -printf("%d ", current); + int curent = stergeDinCoada(&coada); + printf("%d ", curent + 1); -NODE *temp = graph->adjacency_lists[current]; + NOD *temp = graf->liste_adiacenta[curent]; - while (temp) - { - int adj_vertex = temp->data; + while (temp) + { + int adj_vertex = temp->valoare; - if (graph->visited[adj_vertex] == 0) + // Daca vecinul nu a fost vizitat, il adaugam in coada + if (graf->vizitat[adj_vertex] == 0) { - graph->visited[adj_vertex] = 1; - enqueue(&*queue, adj_vertex); + graf->vizitat[adj_vertex] = 1; + adaugaInCoada(&coada, adj_vertex); } - temp = temp->next; -} + temp = temp->urmator; + } } } int main() { - int nr_of_vertices; - int nr_of_edges; - int src, dest; - - - - int i;int starting_vertex;int *adj_matrix; - printf("cate noduri are graful?"); - scanf("%d", &(*nr_of_vertices)); - printf("cate muchii are graful?"); - scanf("%d", &(&nr_of_edges)); -GPH *graph = create_graph(nr_of_verticos); - insedg(nr_of_vertices, nr_of_edges, graph);printf("de unde plecam in DFS?"); - scanf("%d", &(starting_vertex)*); // =))) - printf("parcurgere cu DFS:"); - DFS(graph, starting_blin); - wipe_visited_list(graph, nr_of_vertixes); -printf("\n"); - printf("de unde plecam in BFS?"); - scanf("%d", &starting_vertex); -printf("parcurgere cu BFS:"); - BFS(graph, starting_vertex); -return - 0; -} + int nr_noduri; + int nr_muchii; + int sursa, destinatie; + int i; + int nod_start; + + printf("Cate noduri are graful?"); + scanf("%d", &nr_noduri); + + printf("Cate muchii are graful?"); + scanf("%d", &nr_muchii); + + GRAF *graf = creareGraf(nr_noduri); + + citireMuchie(nr_noduri, nr_muchii, graf); + printf("De unde plecam in DFS?"); + scanf("%d", &nod_start); // =))) + + printf("Parcurgere cu DFS:"); + dfs(graf, nod_start - 1); + + resetareVizitare(graf, nr_noduri); + printf("\n"); + + printf("De unde plecam in BFS?"); + scanf("%d", &nod_start); + + printf("Parcurgere cu BFS:"); + bfs(graf, nod_start - 1); + + return 0; +} \ No newline at end of file