7
7
#include "grafo.h"
8
8
9
9
/* cria grafo com n vertices */
10
- grafo * grafo_novo (int n )
10
+ grafo * grafo_novo (int n )
11
11
{
12
12
int v ;
13
- grafo * g ;
13
+ grafo * g ;
14
14
15
- g = (grafo * )malloc (sizeof (grafo ));
15
+ g = (grafo * )malloc (sizeof (grafo ));
16
16
g -> tamanho = n ;
17
17
18
18
/* cria array de listas de adjacencias */
19
- g -> adjacencias = (int * * )malloc (n * sizeof (int * ));
20
- for ( v = 0 ; v < n ; v ++ )
19
+ g -> adjacencias = (int * * )malloc (n * sizeof (int * ));
20
+ for ( v = 0 ; v < n ; v ++ )
21
21
{
22
- g -> adjacencias [v ] = (int * )calloc (n , sizeof (int ));
22
+ g -> adjacencias [v ] = (int * )calloc (n , sizeof (int ));
23
23
}
24
24
25
25
return g ;
26
26
}
27
27
28
28
/* apaga grafo e liberta memoria */
29
- void grafo_apaga (grafo * g )
29
+ void grafo_apaga (grafo * g )
30
30
{
31
- if (g == NULL )
31
+ if (g == NULL )
32
32
return ;
33
33
34
- if (g -> adjacencias != NULL )
34
+ if (g -> adjacencias != NULL )
35
35
{
36
36
int v ;
37
37
for (v = 0 ; v < g -> tamanho ; v ++ )
@@ -46,102 +46,211 @@ void grafo_apaga(grafo *g)
46
46
retorna 0 se a aresta ja existir e 1 se foi adicionada */
47
47
int grafo_adiciona (grafo * g , int origem , int dest )
48
48
{
49
- if (g == NULL || (origem != 0 && origem != 1 ) || (dest != 0 && dest != 1 ))
49
+ /* alinea 1.1 */
50
+ if (!g )
50
51
return -1 ;
51
- if (g -> adjacencias [origem ][dest ])
52
- {
52
+ if ((origem < 0 ) || (dest < 0 ))
53
+ return -1 ;
54
+ if ((origem > g -> tamanho - 1 ) || (dest > g -> tamanho - 1 ))
55
+ return -1 ;
56
+
57
+ if (g -> adjacencias [origem ][dest ])
53
58
return 0 ;
59
+ else
60
+ {
61
+ g -> adjacencias [origem ][dest ] = 1 ;
62
+ return 1 ;
54
63
}
55
- g -> adjacencias [origem ][dest ] = 1 ;
56
- return 1 ;
57
64
}
65
+
58
66
/* remove do grafo g a aresta entre os vertices origem e destino
59
67
retorna -1 em caso de erro (parametros invalidos)
60
68
retorna 0 se a aresta nao existir e 1 se foi removida */
61
69
int grafo_remove (grafo * g , int origem , int dest )
62
70
{
63
- if (g == NULL || (origem != 0 && origem != 1 ) || (dest != 0 && dest != 1 ))
71
+ /* alinea 1.1 */
72
+ if (!g )
73
+ return -1 ;
74
+ if ((origem < 0 ) || (dest < 0 ))
75
+ return -1 ;
76
+ if ((origem > g -> tamanho - 1 ) || (dest > g -> tamanho - 1 ))
64
77
return -1 ;
65
- if (g -> adjacencias [origem ][dest ] == 0 )
78
+
79
+ if (!g -> adjacencias [origem ][dest ])
66
80
return 0 ;
67
- g -> adjacencias [origem ][dest ] = 0 ;
68
- return 1 ;
81
+ else
82
+ {
83
+ g -> adjacencias [origem ][dest ] = 0 ;
84
+ return 1 ;
85
+ }
69
86
}
70
87
71
88
/* testa no grafo g a aresta entre os vertices origem e destino
72
89
retorna -1 em caso de erro (parametros invalidos)
73
90
retorna 0 se a aresta nao existir e 1 se existir */
74
91
int grafo_aresta (grafo * g , int origem , int dest )
75
92
{
76
- if (g == NULL || (origem != 0 && origem != 1 ) || (dest != 0 && dest != 1 ))
93
+ /* alinea 1.1 */
94
+ if (!g )
77
95
return -1 ;
78
- if (g -> adjacencias [origem ][dest ] == 0 )
79
- return 0 ;
80
- else
81
- return 1 ;
96
+ if ((origem < 0 ) || (dest < 0 ))
97
+ return -1 ;
98
+ if ((origem > g -> tamanho - 1 ) || (dest > g -> tamanho - 1 ))
99
+ return -1 ;
100
+
101
+ return g -> adjacencias [origem ][dest ];
82
102
}
83
103
84
104
/* cria um novo grafo com base numa lista de adjacencias
85
105
parametro adjacencies e' um array de inteiros, representado
86
106
um numero n_edges de arestas.
87
107
retorna um apontador para o grafo criado */
88
- grafo * grafo_deLista (int * adjacencias , int n_arestas )
108
+ grafo * grafo_deLista (int * adjacencias , int n_arestas )
89
109
{
90
110
/* alinea 1.2 */
111
+ if (!adjacencias || (n_arestas < 1 ))
112
+ return NULL ;
91
113
92
- return NULL ;
114
+ int tamanho = adjacencias [0 ];
115
+ for (int i = 1 ; i < 2 * n_arestas ; i ++ )
116
+ {
117
+ if (adjacencias [i ] > tamanho )
118
+ tamanho = adjacencias [i ];
119
+ }
120
+ tamanho += 1 ;
121
+
122
+ grafo * g = grafo_novo (tamanho );
123
+ if (!g )
124
+ return NULL ;
125
+
126
+ for (int i = 0 ; i < n_arestas ; i ++ )
127
+ {
128
+ if (grafo_adiciona (g , adjacencias [2 * i ], adjacencias [2 * i + 1 ]) == -1 )
129
+ {
130
+ grafo_apaga (g );
131
+ return NULL ;
132
+ }
133
+ }
134
+ return g ;
93
135
}
94
136
95
137
/* cria e retorna um vetor de inteiros contendo os vertices
96
138
de destino de todas as arestas com origem em i */
97
- vetor * grafo_arestasSaida (grafo * g , int i )
139
+ vetor * grafo_arestasSaida (grafo * g , int i )
98
140
{
99
141
/* alinea 1.3 */
142
+ if (!g || (i < 0 ))
143
+ return NULL ;
144
+
145
+ vetor * v = vetor_novo ();
146
+ if (!v )
147
+ return NULL ;
148
+
149
+ // complexidade: O(g->tamanho)
150
+ for (int j = 0 ; j < g -> tamanho ; j ++ )
151
+ {
152
+ if (grafo_aresta (g , i , j ))
153
+ {
154
+ if (vetor_insere (v , j , -1 ) == -1 )
155
+ {
156
+ vetor_apaga (v );
157
+ return NULL ;
158
+ }
159
+ }
160
+ }
100
161
101
- return NULL ;
162
+ return v ;
102
163
}
103
164
104
165
/* cria e retorna um vetor de inteiros contendo os vertices
105
166
de origem de todas as arestas com destino a i */
106
- vetor * grafo_arestasEntrada (grafo * g , int i )
167
+ vetor * grafo_arestasEntrada (grafo * g , int i )
107
168
{
108
169
/* alinea 1.3 */
170
+ if (!g || (i < 0 ))
171
+ return NULL ;
109
172
110
- return NULL ;
173
+ vetor * v = vetor_novo ();
174
+ if (!v )
175
+ return NULL ;
176
+
177
+ // complexidade: O(g->tamanho)
178
+ for (int j = 0 ; j < g -> tamanho ; j ++ )
179
+ {
180
+ if (grafo_aresta (g , j , i ))
181
+ {
182
+ if (vetor_insere (v , j , -1 ) == -1 )
183
+ {
184
+ vetor_apaga (v );
185
+ return NULL ;
186
+ }
187
+ }
188
+ }
189
+
190
+ return v ;
111
191
}
112
192
113
193
/* verifica se o grafo g e' completo
114
194
retorna -1 em caso de erro (parametros invalidos)
115
195
retorna 1 se o grafo for completo e 0 se nao o for */
116
- int grafo_completo (grafo * g )
196
+ int grafo_completo (grafo * g )
117
197
{
118
198
/* alinea 1.4 */
199
+ if (!g )
200
+ return -1 ;
119
201
120
- return 0 ;
202
+ // complexidade: O(g->tamanho^2)
203
+ for (int i = 0 ; i < g -> tamanho ; i ++ )
204
+ {
205
+ for (int j = 0 ; j < i ; j ++ )
206
+ {
207
+ if (!grafo_aresta (g , i , j ) && !grafo_aresta (g , j , i ))
208
+ return 0 ;
209
+ }
210
+ }
211
+ return 1 ;
121
212
}
122
213
123
214
/* verifica se o vertice i do grafo g e' uma celebridade
124
215
retorna -1 em caso de erro (parametros invalidos)
125
216
retorna 1 se o vertice for uma celebridade e 0 se nao o for */
126
- int grafo_eCelebridade (grafo * g , int i )
217
+ int grafo_eCelebridade (grafo * g , int i )
127
218
{
128
219
/* alinea 1.5 */
220
+ if (!g || (i < 0 ))
221
+ return -1 ;
129
222
130
- return 0 ;
223
+ // complexidade: O(n) (onde n = g->tamanho)
224
+ for (int j = 0 ; j < g -> tamanho ; j ++ )
225
+ {
226
+ if (j == i )
227
+ continue ;
228
+ if (grafo_aresta (g , i , j ) || !grafo_aresta (g , j , i ))
229
+ return 0 ;
230
+ }
231
+ return 1 ;
131
232
}
132
233
133
234
/* verifica se o grafo g tem pelo menos uma celebridade
134
235
retorna -1 em caso de erro (parametros invalidos)
135
236
retorna 1 se existir uma celebridade e 0 se nao existir */
136
- int grafo_temCelebridade (grafo * g )
237
+ int grafo_temCelebridade (grafo * g )
137
238
{
138
239
/* alinea 1.5 */
240
+ if (!g )
241
+ return -1 ;
139
242
243
+ // complexidade: O(n^2) (onde n = g->tamanho)
244
+ for (int i = 0 ; i < g -> tamanho ; i ++ )
245
+ {
246
+ if (grafo_eCelebridade (g , i ))
247
+ return 1 ;
248
+ }
140
249
return 0 ;
141
250
}
142
251
143
252
/* imprime as adjacencias do grafo */
144
- void grafo_imprime (grafo * g )
253
+ void grafo_imprime (grafo * g )
145
254
{
146
255
int i , j ;
147
256
@@ -151,11 +260,11 @@ void grafo_imprime(grafo *g)
151
260
for (i = 0 ; i < g -> tamanho ; i ++ )
152
261
{
153
262
printf ("%d: " , i );
154
- for (j = 0 ; j < g -> tamanho ; j ++ )
263
+ for (j = 0 ; j < g -> tamanho ; j ++ )
155
264
{
156
- if (g -> adjacencias [i ][j ] != 0 )
265
+ if (g -> adjacencias [i ][j ] != 0 )
157
266
printf ("%d " , j );
158
267
}
159
268
printf ("\n" );
160
269
}
161
- }
270
+ }
0 commit comments