Documente Academic
Documente Profesional
Documente Cultură
}
void tree_lvl(Node node, int lvl, int crt)
{
if (!node || crt > lvl)
return;
/* suntem pe nivelul corespunzator sau
unul mai mic si avem noduri de afisat */
if (lvl == crt)
printf("%c ", node->key);
tree_lvl(node->left, lvl, crt + 1);
tree_lvl(node->right, lvl, crt + 1);
}
int tree_cnt1(Node node)
{
if (!node)
return 0;
return 1 + tree_cnt1(node->left) +
tree_cnt1(node->right);
}
int tree_cnt2(Node node)
{
if (!node)
return 0;
// verificam cati descendenti are
int cnt = 0; // initial nu-l numaram
int des = (node->left ? 1 : 0) +
(node->right ? 1 : 0);
if (des == 1) // un descendent
cnt = 1; // deci numaram
return cnt + tree_cnt2(node->left) +
tree_cnt2(node->right);
}
void tree_kelem(Node node, const int k,
char * const chr, int firstTime)
{
static int cnt = 0;
if (firstTime)
cnt = 0;
if (!node || cnt == k)
return;
tree_kelem(node->left, k, chr, 0);
++cnt;
if (cnt == k)
*chr = node->key;
tree_kelem(node->right, k, chr, 0);
}
Problema 2
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "digraf.h"
void creeaza(Digraf * digraf, char * fname)
{
FILE * fin = fopen(fname, "r");
if (!fin) {
fprintf(stderr, "Eroare: fisierul \
nu a putut fi deschis\n");
exit(EXIT_FAILURE);
}
// citim numarul de varfuri
fscanf(fin, "%d", &digraf->nodes);
// citim numarul de arce
fscanf(fin, "%d", &digraf->edges);
/* acum pentru fiecare arc citim
perechile de noduri */
int ** l; // lista de adiacenta
l = (int **)malloc((digraf->nodes + 1) *\
sizeof(int *));
for (int i = 1; i <= digraf->nodes; ++i) {
l[i] = (int*)malloc(sizeof(int));
l[i][0] = 0;
/* ^ in primul element retinem mereu
numarul de vecini ai varfului `i` */
}
for (int i = 0; i < digraf->edges; ++i) {
int x, y;
fscanf(fin, "%d %d", &x, &y);
// nodului `x` ii adaugam vecinul `y`
l[x] = (int *)realloc(l[x], sizeof(int) *\
(1 + ++l[x][0]));
l[x][l[x][0]] = y;
}
digraf->list = l; // salvam lista
fclose(fin);
}
int grad_int(Digraf digraf, int node)
{
/**
* Pentru fiecare nod, functia citeste
* fiecare vecin si vede daca coincide
* cu varful `node`, iar daca coincide
* numaram ca intrare.
*/
int grad = 0;
for (int i = 1; i <= digraf.nodes; ++i)
for (int j = 1; j <= digraf.list[i][0]; ++j)
if (digraf.list[i][j] == node) {
++grad;
break;
}
return grad;
}
int grad_ext(Digraf digraf, int node)
{
/**
* Returneaza numarul de vecini
* ai varfului `node`.
*/
return digraf.list[node][0];
}
if (seen[j])
++cnt;
if (cnt != digraf.nodes) {
free(seen);
return 0; // nu este tare conex
}
}
free(seen);
return 1; // este tare conex
}
Problema 3
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "graph.h"
// definitiile prototipurilor private
static void dfs(int **, int, int *);
void graph_create(Graph * graph, char * fname)
{
FILE * fin = fopen(fname, "r");
if (!fin) {
fprintf(stderr, "Eroare: fisierul \
nu a putut fi deschis\n");
exit(EXIT_FAILURE);
}
// citim numarul de varfuri
fscanf(fin, "%d", &graph->nodes);
// citim numarul de arce
fscanf(fin, "%d", &graph->edges);
/* acum pentru fiecare arc citim
perechile de noduri */
int ** l; // lista de adiacenta
l = (int **)malloc((graph->nodes + 1) *\
sizeof(int *));
for (int i = 1; i <= graph->nodes; ++i) {
l[i] = (int*)malloc(sizeof(int));
l[i][0] = 0;
/* ^ in primul element retinem mereu
numarul de vecini ai varfului `i` */
}
for (int i = 0; i < graph->edges; ++i) {
/* spre deosebire de graful orientat
in graful neorientat `y` este vecinul
lui `x`, dar si invers */
int x, y;
fscanf(fin, "%d %d", &x, &y);
// nodului `x` ii adaugam vecinul `y`
l[x] = (int *)realloc(l[x], sizeof(int) *\
(1 + ++l[x][0]));
l[x][l[x][0]] = y;
// acelasi lucru si pentru `y`
l[y] = (int *)realloc(l[y], sizeof(int) *\
(1 + ++l[y][0]));
l[y][l[y][0]] = x;
}
graph->list = l; // salvam lista
fclose(fin);
}
void graph_destroy(Graph * graph)
{
for (int i = 1; i <= graph->nodes; ++i)
free(graph->list[i]);
free(graph->list);
graph->nodes = 0;
graph->edges = 0;
}
int graph_is_tree(const Graph graph)
{
/**
* Functia verifica daca graful dat ca parametru
* este un arbore.
* Pentru a pastra lucrurile simple si ca executia
* algoritmului sa ia un timp liniar, ajunge sa
* verificam daca graful are N-1 muchii (unde N
* este numarul de noduri) si sa parcurgem graful
* pana vizitam toate nodurile posibile.
*
* Daca graful are mai putine muchii, atunci nu
* are cum sa fie conex, deci nu poate fi arbore.
* Daca graful are mai multe noduri, atunci cu
* siguranta contine cicluri (si poate fi conex
* sau nu), dar arborele trebuie sa fie aciclic.
*
* Daca nodurile sunt in regula, urmeaza sa le
* vizitam O(M). Daca am reusit sa le vizitam
* pe toate O(N) atunci inseamna ca avem un graf
* neorientat conex aciclic, adica un arbore,
* complexitatea finala fiind O(N+M).
*/
if (graph.nodes - 1 != graph.edges)
return 0;
size_t size = sizeof(int) * (graph.nodes + 1);
int * seen = (int *)malloc(size);
memset(seen, 0, size);
dfs(graph.list, 1, seen);
for (int i = 1; i <= graph.nodes; ++i)
if (!seen[i]) {
// opa, un nod nu a fost vizitat :)
free(seen);
return 0;
}
free(seen);
return 1; // este arbore
}
static void dfs(int ** list, int node, int * seen)
{
seen[node] = 1;
for (int i = 1; i <= list[node][0]; ++i)
if (!seen[list[node][i]])
dfs(list, list[node][i], seen);
}