Você está na página 1de 12

IFMA

DISCIPLINA ESTRUTURA DE DADOS


ALUNOS: FREDERICO HADAN cd: si1313002-21

CSAR LOPES cd: si1212001-21

1-Para um dado grafo de entrada,escreva uma funo que conte a partir de um vrtice de
origem,qual o nmero de vrtices presentes a uma distncia par da origem. Ilustre a execuo do
seu algortimo em um grafo qualquer.
A funo exigida utiliza a funo BFS (G,s) para calcular a distncia d [u] da origem aos demais
vrtices;
//Recebe como entrada o grafo G e o vrtice de origem S;
contar (G,s)
Aplicar BFS (G,s)
cont 0
//qtd de vrtices a uma dist. Par de S;
para cada u existe um G[V]
//percorre o grafo G por vrtices;
faa se MOD (d[u], 2)=0 //se o mdulo da diviso de d [u] por 2=0, o vrtice est a uma distncia
par;
ento cont cont +1
// increment cont (sada desejada);
return cont
// retorna a qtd de vrtice u a uma distncia par da origem S;
*Ilustrando a execuo do algortimo acima:
-Aps aplicar o algortimo da busca em largura no grafo G abaixo,considerando a origem
S=A,obtivemos:

Com o grafo G atualizado para cada


vrtice com seu respectivos valores
d [u], e feita a contagem dos vrtices
localizados uma distncia par da
origem s=A: que so os vrtices
B,D,E e F; a varivel cont
atualizada com o valor 4 no exemplo
e ao final retomada pela funo
CONTAR (G,S).

Cdigo completo:
#include <stdio.h>
#include <stdlib.h>
#include "fila.cpp"
#define NULO -1
#define INF 100000
#define TAM 9
typedef struct grafTS{
int M[TAM][TAM];
int numVertice;
int numAresta;
int d[TAM];
int pi[TAM];

int time;
char cor[TAM];
Fila fila;
}Graf_;
typedef Graf_ * Grafo;
void inicializaMatriz(Grafo grafo, int nv){
int i, j;
for(i = 1; i <= nv; i++){
for(j = 1; j <= nv; j++){
grafo->M[i][j] = 0;
}
}
}
void inicializa(Grafo grafo, int ini, int nv, int na){
int i;
inicializaMatriz(grafo, nv);
for(i = 1; i <= nv; i++){
grafo->d[i] = INF;
grafo->pi[i] = NULO;
}
grafo->d[ini]=0;
grafo->numVertice = nv;
grafo->numAresta = na;

}
Grafo newGrafo(int ini, int nv, int na){
Grafo grafo = NULL;
grafo = (Graf_*)malloc(sizeof(Graf_));
inicializa(grafo, ini, nv,na);
return grafo;
}
void addAresta(Grafo grafo, int v1, int v2){
grafo->M[v1][v2] = 1;
}
void exibirMatrizAdjacencias(Grafo grafo, int nv){
int i, j;
printf("\nMatriz de ajacencias:\n");
for(i = 1; i <= nv; i++){
for(j = 1; j <= nv; j++){
printf("\t%d", grafo->M[i][j]);
if(j == nv)
printf("\n");
}
}
}
void bfs(Grafo grafo, int inicio){
int i;
for(i = 1; i <= grafo->numVertice; i++){
grafo->cor[i] = 'B';
grafo->d[i] = INF;
grafo->pi[i] = NULL;
}

grafo->cor[inicio] = 'C';
grafo->d[inicio] = 0;
grafo->pi[inicio] = NULL;
grafo->fila = newFila();
inserirFila(grafo->fila, inicio);
while(!filaVazia(grafo->fila)){
int topo = getTopo(grafo->fila);
excluirFila(grafo->fila);
for(i = 1; i <= grafo->numVertice; i++){
if(grafo->M[topo][i] != 0){
if(grafo->cor[i] == 'B'){
grafo->cor[i] = 'C';
grafo->d[i] = grafo->d[topo] + 1;
grafo->pi[i] = topo;
inserirFila(grafo->fila, i);
}
}
}
grafo->cor[topo] = 'P';
}
}
void destroy(Grafo grafo){
free(grafo);
}
void exibirVerticesDetalhado(Grafo grafo, int nv){
int i;
printf("\nVertices com detalhes:\n");
for(i = 1; i <= nv; i++){
printf("\n v= %d \t d= %d \t pi= %d", i, grafo->d[i], grafo->pi[i]);
}
}
void exibirPercurso(Grafo grafo, int s, int v){

if(v == s){
printf("%d", s);
}else if(grafo->pi[v] == NULO){
fprintf(stdout,"nao tem caminho %d a %d ", s, v);
}else{
exibirPercurso(grafo, s, grafo->pi[v]);
fprintf(stdout," %d ", v);
}

int contar(Grafo grafo, int inicio){


int cont=0;
bfs(grafo, inicio);
for (int i = 1; i <= grafo->numVertice; i++){
if(grafo->d[i] !=0 && grafo->d[i] % 2 == 0){
cont ++;
}
}
return cont;
}

main(){
int i,nv,na,v1,v2,peso;
puts("\n*** ALGORITMO DE DFS ***\n");
puts("\n numero de vertices para o grafo : ");
scanf("%d",&nv);
puts("\nnumero de arestas para o grafo : ");
scanf("%d",&na);
Grafo grafo = newGrafo(1, nv, na);
for(i = 0; i < na; i++){
scanf("%d %d",&v1, &v2);
addAresta(grafo, v1, v2);
}

exibirMatrizAdjacencias(grafo,nv);
bfs(grafo, 1);
exibirVerticesDetalhado(grafo, nv);
printf("\ncontagem de vertices com distancia par: %d", contar(grafo,1));
destroy(grafo);

2- Execute o algortimo de Dijkstra,passo a passo,considerando o grafo abaixo.


A

F,7

A,4

2
2

C,5

F
7
D

B,9

C,8

Q= | A|B|C|D|E|F|
Q={ A,C,F,B,E,D}

12

A,0

F,7

A,4

B,9

C,8

C,5

Cdigo completo:
#include <stdio.h>
#include <stdlib.h>
#include "fila.cpp"
#define NULO -1
#define INF 100000
#define TAM 7
typedef struct graf{
int M[TAM][TAM];
int numVertice;
int numAresta;
int d[TAM],pi[TAM];
Fila filaPrecedente;
Fila filaPrioridade;
}Graf_;
typedef Graf_ * Grafo;
void inicializaMatriz(Grafo grafo, int nv){
int i, j;
for(i = 1; i <= nv; i++){
for(j = 1; j <= nv; j++){
grafo->M[i][j] = 0;
}
}
}
void inicializa(Grafo grafo, int ini, int nv, int na){
int i;

inicializaMatriz(grafo, nv);
for(i = 1; i <= nv; i++){
grafo->d[i] = INF;
grafo->pi[i] = NULO;
}
grafo->d[ini]=0;
grafo->numVertice = nv;
grafo->numAresta = na;
grafo->filaPrioridade = newFila();
grafo->filaPrecedente = newFila();
}
Grafo newGrafo(int ini, int nv, int na){
Grafo grafo = NULL;
grafo = (Graf_*)malloc(sizeof(Graf_));
inicializa(grafo, ini, nv,na);
return grafo;
}
void relaxa(Grafo grafo, int ori,int dest){
if(grafo->d[dest] > (grafo->d[ori] + grafo->M[ori][dest]))
{
grafo->d[dest] = (grafo->d[ori] + grafo->M[ori][dest]);
grafo->pi[dest] = ori;
}
}
void addAresta(Grafo grafo, int v1, int v2, int peso){
grafo->M[v1][v2] = peso;
}
void transfereVertices(Grafo grafo){
int i;
for(i = 1; i <= grafo->numVertice; i++){
inserirFila(grafo->filaPrioridade,i);
}
}
int extractMin(Grafo grafo){
int i, valorMenor = INF,indiceMenor, valorItem;No noInc;
for (noInc = grafo->filaPrioridade->inicio; noInc != NULL; noInc = noInc->next){
valorItem = grafo->d[noInc->elemento];
if(valorItem < valorMenor){
valorMenor = grafo->d[noInc->elemento];
indiceMenor = noInc->elemento;
}
}
excluirPorElemento(grafo->filaPrioridade, indiceMenor);
return indiceMenor;
}
void dijkstra(Grafo grafo){
int i;
transfereVertices(grafo);
while(!filaVazia(grafo->filaPrioridade)){
int indiceMenor = extractMin(grafo);
inserirFila(grafo->filaPrecedente, indiceMenor);

for(i = 1; i <= grafo->numVertice; i++){


int adj = grafo->M[indiceMenor][i];
if(adj != 0){
relaxa(grafo, indiceMenor, i);
}
}

}
void destroy(Grafo grafo){
free(grafo);
}
void exibirPercurso(Grafo grafo, int s, int v){
if(v == s){
printf("%d", s);
}else if(grafo->pi[v] == NULO){
fprintf(stdout,"nao tem caminho %d a %d ", s, v);
}else{
exibirPercurso(grafo, s, grafo->pi[v]);
fprintf(stdout," %d ", v);
}
}
void exibirMatrizAdjacencias(Grafo grafo, int nv){
int i, j;
printf("\nMatriz de ajacencias:\n");
for(i = 1; i <= nv; i++){
for(j = 1; j <= nv; j++){
printf("\t%d", grafo->M[i][j]);
if(j == nv)
printf("\n");
}
}
}
void exibirVerticesDetalhado(Grafo grafo, int nv){
int i;
printf("\nVertices com detalhes:\n");
for(i = 1; i <= nv; i++){
printf("\n v= %d \t d= %d \t pi= %d", i, grafo->d[i], grafo->pi[i]);
}
}
int main()
{
int i,nv,na,v1,v2,peso;
puts("\n*** ALGORITMO DE DIJKSTRA ***\n");
puts("\n numero de vertices para o grafo : ");
scanf("%d",&nv);
puts("\nnumero de arestas para o grafo : ");
scanf("%d",&na);
Grafo grafo = newGrafo(1, nv, na);
for(i = 0; i < na; i++){
scanf("%d %d %d",&v1, &v2, &peso);
addAresta(grafo, v1, v2, peso);
}

exibirMatrizAdjacencias(grafo,nv);
dijkstra(grafo);

printf("Percurso de menor custo: \n");


exibirVerticesDetalhado(grafo, nv);
destroy(grafo);

3-Respostas de Ramonilton
Podemos ajudar o amigo Ramonilton aplicando o algortimo de ???
Para resolver o problema:
Aplicar o DSF no grafo em questo:
O DFS consiste em visitar todos os vrtices do grafo,atualizando-os com 2 informaes: um timer
para quando o vrtice u foi descoberto (d[u]), e outro timer para quando todos os vrtices v
adjacentes ao vrtice u,foram finalizados (f(u)).
Aps a aplicao do algortimo de Busca em Profundidade,ficamos com o grafo abaixo:
5
7

13/14

1/12

15/16

10/11

2/9

11

3/4

7/8

5/6
2

10

Com os valores de f(u) de cada vrtice calculado, ordena-se os mesmos em ordem Decrescente
de f (u),e insere-os em uma lista, para posteriores consultas:
A resoluo do problema acima pode ser encontrado ao visitar a lista:
Lista L= [3,5,7,8,11,10,9,2}
Cdigo completo:
#include <stdio.h>
#include <stdlib.h>
#include "lista.cpp"
#define NULO -1
#define INF 100000
#define TAM 10
typedef struct grafTS{
int M[TAM][TAM];
int numVertice;
int numAresta;

int i[TAM];
int f[TAM];
int pi[TAM];
int time;
char cor[TAM];
Lista listaTS;
}GrafTS_;
typedef GrafTS_ * GrafoTS;
void inicializaMatriz(GrafoTS grafo, int nv){
int i, j;
for(i = 1; i <= nv; i++){
for(j = 1; j <= nv; j++){
grafo->M[i][j] = 0;
}
}
}
void inicializa(GrafoTS grafo, int ini, int nv, int na){
int i;
inicializaMatriz(grafo, nv);
for(i = 1; i <= nv; i++){
grafo->i[i] = 0;
grafo->f[i] = 0;
grafo->pi[i] = NULO;
}
grafo->numVertice = nv;
grafo->numAresta = na;
grafo->listaTS = newLista();
}
GrafoTS newGrafo(int ini, int nv, int na){
GrafoTS grafo = NULL;
grafo = (GrafTS_*)malloc(sizeof(GrafTS_));
inicializa(grafo, ini, nv,na);
return grafo;
}

void addAresta(GrafoTS grafo, int v1, int v2){


grafo->M[v1][v2] = 1;
}
void exibirMatrizAdjacencias(GrafoTS grafo, int nv){
int i, j;
printf("\nMatriz de ajacencias:\n");
for(i = 1; i <= nv; i++){
for(j = 1; j <= nv; j++){
printf("\t%d", grafo->M[i][j]);
if(j == nv)
printf("\n");
}
}
}
void dfsVisit(GrafoTS grafo, int indiceVertice){
int i;

grafo->cor[indiceVertice] = 'C';
grafo->time ++;
grafo->i[indiceVertice] = grafo->time;
for(i = 1; i <= grafo->numVertice; i++){
if(grafo->M[indiceVertice][i] != 0){
if(grafo->cor[i] == 'B'){
grafo->pi[i] = indiceVertice;
dfsVisit(grafo, i);
}
}
}
grafo->cor[indiceVertice] = 'P';
grafo->f[indiceVertice] = grafo->time = grafo->time + 1;
inserirLista(grafo->listaTS, indiceVertice);
}
void dfsTs(GrafoTS grafo){
int i;
for(i = 1; i <= grafo->numVertice; i++){
grafo->cor[i] = 'B';
grafo->pi[i] = NULL;
}
grafo->time = 0;

for(i = 1; i <= grafo->numVertice; i++){


if(grafo->cor[i] == 'B'){
dfsVisit(grafo, i);
}
}

void destroy(GrafoTS grafo){


free(grafo);
}
void exibirPercurso(GrafoTS grafo){
No noInc;
printf("Impressao percurso topologicalSort: \n");
for (noInc = grafo->listaTS->inicio; noInc != NULL; noInc = noInc->next){
printf("%d \t ", noInc->elemento);
}
}
void exibirVerticesDetalhado(GrafoTS grafo, int nv){
int i;
printf("\nVertices com detalhes:\n");
for(i = 1; i <= nv; i++){
printf("\n v= %d \t i= %d \t f= %d \t pi= %d", i, grafo->i[i], grafo->f[i], grafo->pi[i]);
}
}
main(){
int i,nv,na,v1,v2,peso;
puts("\n*** ALGORITMO DE DFS ***\n");
puts("\n numero de vertices para o grafo : ");
scanf("%d",&nv);
puts("\nnumero de arestas para o grafo : ");
scanf("%d",&na);

GrafoTS grafo = newGrafo(1, nv, na);


for(i = 0; i < na; i++){
scanf("%d %d",&v1, &v2);
addAresta(grafo, v1, v2);
}
exibirMatrizAdjacencias(grafo,nv);
dfsTs(grafo);
exibirPercurso(grafo);
exibirVerticesDetalhado(grafo, nv);
destroy(grafo);
}

4) Armazene os seguintes valores em sequncia: 82,31,28,4,45,27,59,79,35 em uma tabela hash


de tamanho 11. Utilize as seguintes fues de hash:
(a) Resto da diviso h(k) = k mod 11 com hashing linear ;
(b) Multiplicao: h(k) = k + i mod 11, com = 0.61;
Para cada caso mostre como so tratadas as colises e a tabela final resultante.
Resposta:
a)
82 mod 11 = 5 (sem conflito)
31 mod 11 = 9 (sem conflito)
28 mod 11 = 6 (sem conflito)
4 mod 11 = 4 (sem conflito)
45 mod 11 = 1 (sem conflito)
27 mod 11 = 5 (conflito)
59 mod 11 = 4 (conflito)
79 mod 11 = 2 (sem conflito)
35 mod 11 = 2 (conflito)

H(k)
5
9
6
4
1
7
8
2
3

Chave
82
31
28
4
45
27
59
79
35

*Conflito ao inserir elemento 27: ao inserir o elemento 27 na posio 5 j havia o elemento 82,
ao tentar a posio 6 (seguinte) foi encontrado o elemento 28, inseriu-se portanto na posio 7
(seguinte).
*Conflito ao inserir elemento 59: ao inserir o elemento 59 na posio 4 j havia o elemento 4, ao
tentar a posio 5 (seguinte) foi encontrado o elemento 82, o mesmo ocorreu na posio 6 que
continha o elemento 28 e na posio 7 que continha o elemento 27, inseriu-se portanto na posio
8 (seguinte).
*Conflito ao inserir elemento 35: ao inserir o elemento 35 na posio 2 j havia o elemento 79,
inseriu-se portanto na posio 3 (seguinte).

Cdigo completo:
#include <stdio.h>
#include <stdlib.h>
#define NULO -1
#define TAM 11
void inserirKey(int key,int * keys){
int posicao = key % TAM;

if(keys[posicao] == NULO){
keys[posicao] = key;
}else{
while(posicao <= TAM ){
posicao = posicao + 1;
if(keys[posicao] != NULO){
keys[posicao] = key;
break;
}
}
}

main(){
int keys[TAM],i,numKeys,key, keysEnter[TAM];
for (int i = 0; i < TAM; i++){
keys[i] = NULO;
}
printf("Entre com o numero de chaves que deseja inserir:\n");
scanf("%d",&numKeys);
for (int i = 0; i < numKeys; i++){
scanf("%d",&keysEnter[i]);
}
for (int i = 0; i < numKeys; i++){
inserirKey(keysEnter[i], keys);
}
for (int i = 0; i < TAM; ++i)
{
printf("Keys[%d] = %d",i,keys[i]);
}
}

Você também pode gostar