Implementações de DFS e BFS em Grafos

Métodos de Travsesia em Grafos

Dois métodos fundamantais para percorrer grafos:

  • DFS (Busca em Profundidade)
  • BFS (Busca em Largura) - implementada com fila

DFS com Lista de Adjacência

#define TAM_MAX 100
#define INF 65535

typedef struct NoAdjacente* PonteiroNo;
struct NoAdjacente {
  int Vertice;
  int Peso;
  PonteiroNo Proximo;
};

typedef struct {
  PonteiroNo PrimeiraAresta;
  char Dado;
} CelulaLista[TAM_MAX];

typedef struct GrafoLista* GrafoL;
struct GrafoLista {
  int Vertices;
  int Arestas;
  CelulaLista Adjacencias;
};

GrafoL CriarGrafo(int TotalVertices) {
  GrafoL Novo = (GrafoL)malloc(sizeof(struct GrafoLista));
  Novo->Vertices = TotalVertices;
  Novo->Arestas = 0;
  for(int v = 0; v < TotalVertices; v++)
    Novo->Adjacencias[v].PrimeiraAresta = NULL;
  return Novo;
}

void InserirAresta(GrafoL G, int Origem, int Destino, int Peso) {
  PonteiroNo NovaAresta = (PonteiroNo)malloc(sizeof(struct NoAdjacente));
  NovaAresta->Vertice = Destino;
  NovaAresta->Peso = Peso;
  NovaAresta->Proximo = G->Adjacencias[Origem].PrimeiraAresta;
  G->Adjacencias[Origem].PrimeiraAresta = NovaAresta;
}

int Visitados[TAM_MAX];
void Visitar(int V) {
  printf("Visitado: %d\n", V);
}

void DFS(GrafoL G, int V) {
  Visitar(V);
  Visitados[V] = 1;
  
  PonteiroNo Atual = G->Adjacencias[V].PrimeiraAresta;
  while(Atual) {
    if(!Visitados[Atual->Vertice])
      DFS(G, Atual->Vertice);
    Atual = Atual->Proximo;
  }
}

BFS com Matriz de Adjacência

typedef struct GrafoMatriz* GrafoM;
struct GrafoMatriz {
  int Vertices;
  int Arestas;
  int Matriz[TAM_MAX][TAM_MAX];
  char Dados[TAM_MAX];
};

GrafoM IniciarGrafo(int TotalVertices) {
  GrafoM Novo = (GrafoM)malloc(sizeof(struct GrafoMatriz));
  Novo->Vertices = TotalVertices;
  Novo->Arestas = 0;
  for(int i = 0; i < TotalVertices; i++)
    for(int j = 0; j < TotalVertices; j++)
      Novo->Matriz[i][j] = INF;
  return Novo;
}

#define CAPACIDADE 50
int Fila[CAPACIDADE];
int Inicio = 0, Fim = -1, Itens = 0;

void Enfileirar(int Elemento) {
  Fim = (Fim + 1) % CAPACIDADE;
  Fila[Fim] = Elemento;
  Itens++;
}

int Desenfileirar() {
  int Elemento = Fila[Inicio];
  Inicio = (Inicio + 1) % CAPACIDADE;
  Itens--;
  return Elemento;
}

int Vazio() { return Itens == 0; }

void BFS(GrafoM G, int Inicio) {
  int Marcados[TAM_MAX] = {0};
  Enfileirar(Inicio);
  Visitar(Inicio);
  Marcados[Inicio] = 1;

  while(!Vazio()) {
    int Atual = Desenfileirar();
    for(int w = 0; w < G->Vertices; w++) {
      if(!Marcados[w] && G->Matriz[Atual][w] != INF) {
        Enfileirar(w);
        Visitar(w);
        Marcados[w] = 1;
      }
    }
  }
}

Aplicação: Porblema de Escape

struct Ponto {
  int x;
  int y;
} Locais[TAM_MAX];

float Distancia(int x1, int y1, int x2, int y2) {
  return sqrt(pow(x2-x1, 2) + pow(y2-y1, 2));
}

int VerificarEscape(GrafoM G, int Vertice, float Limite) {
  Visitados[Vertice] = 1;
  
  float d1 = Distancia(0, 50, Locais[Vertice].x, Locais[Vertice].y);
  float d2 = Distancia(0, -50, Locais[Vertice].x, Locais[Vertice].y);
  float d3 = Distancia(50, 0, Locais[Vertice].x, Locais[Vertice].y);
  float d4 = Distancia(-50, 0, Locais[Vertice].x, Locais[Vertice].y);
  
  if(d1 <= Limite || d2 <= Limite || d3 <= Limite || d4 <= Limite)
    return 1;

  for(int i = 0; i < G->Vertices; i++) {
    if(!Visitados[i] && G->Matriz[Vertice][i])
      if(VerificarEscape(G, i, Limite))
        return 1;
  }
  return 0;
}

Tags: dfs bfs lista-de-adjacência matriz-de-adjacência Grafos

Publicado em 6-29 05:24