Está en la página 1de 7

EJEMPLO 16.

El recorrido en profundidad empieza visitando el vértice de partida y a continuación pasa a visitar en


profundidad cada vértice adyacente no visitado. Puede realizarse de forma recursiva o bien iterativa eliminando
la recursividad. Una codificación recusiva del recurrido en profundiad puede consultarse en el ejercicio resuelto
16.4, y una codificación iterartiva del recorrido en el ejercicio resuelto 16.5.

EJEMPLO 16.6

Al recorrerlo en profundidad a partir del vértice d, el conjunto de vértices que se alcanza es {d, c, b, e} y
repitiendo el recorrido en el grafo inverso se obtienen los vértices ascendientes: {d, b, c, e}. Los vértices
comunes (en este ejemplo d, b, c, e) forman una componente fuertemente conexa.

PROBLEMAS RESUELTOS

16.1.

Codificación

#include <stdio.h>
#define <stdlib.h>
#define n 10
#define True 1
#define False 0
struct Grafo
{
int V[n], A[n][n];
};
struct Arco
{
int u,v;
};

void Inicializa (Grafo *G)


{ /* no tiene ni vértices ni arcos */
int i,j;
for(i = 0; i < n; i++)
{
G->V[i] = False;
for(j = 0; j < n; j++)
G->A[i][j] = False;
}
}

void AnadeVertice(Grafo *G, int v)


{
/*Añade el vértice v al grafo */
if ((0 <= v) && (v < n))
G->V[v] = True;
}
void AnadeArco( Grafo *G, Arco Arc)
{
/* Añade un arco al grafo, para lo cual debe añadir po si no están
primeramente los dos vértices del arco*/
AnadeVertice(G, Arc.u);
AnadeVertice(G,Arc.v);
G->A[Arc.u][Arc.v] = True;
}

void BorraArco(Grafo *G, Arco Arc)


{
/* elimina el arco del grafo*/
G->A[Arc.u][Arc.v] = False;
}

void BorraVertice( Grafo *G, int v)


{
/* elmimina el vértice v y todos los arcos que lo tengan de origen o
destino*/
int i;
if((0 <= v) && (v < n))
{
G->V[v] = False;
for ( i = 0; i < n; i++)
{
G->A[i][v] = False;
G->A[v][i] = False;
}
}
}

int PerteneceVertice( Grafo G, int v)


{
/* Decide si un vértice está en el grafo *7
if(( 0 <= v) && (v < n))
return (G.V[v]) ;
else
return(False);
}

int PerteneceArco( Grafo G, Arco Arc)


{
/* decide si un arco está en el grafo */
int sw;
sw = PerteneceVertice(G,Arc.u) && PerteneceVertice(G,Arc.v);
if(sw)
return (G.A[Arc.u][Arc.v]);
else
return(False);
}

16.2.

#include <stdio.h>
#include <stdlib.h>
#define False 0
#define True 1
struct Arco
{
int u,v;
float valor;
};
struct ItemAdy
{
int v;
float valor;
};
struct ListaAdy
{
ItemAdy el;
struct ListaAdy* sig;
};
struct ItemG
{
int v;
ListaAdy *Ady;
} ;
struct ListaG
{
ItemG el ;
ListaG *sig;
} ;

void Inicializa(ListaG **Primero)


{
(*Primero)=NULL;
}
int PerteneceConjuntoAdy (ListaAdy* Primero, ItemAdy dato)
{
ListaAdy *ptr;
for (ptr = Primero; ptr != NULL; ptr = ptr ->sig )
if (ptr-> el.v == dato.v)
return True;
return False;
}

void AnadeConjuntoAdy(ListaAdy** Primero, ItemAdy dato)


{
/*añade vértice a la lista de adyacencia */
ListaAdy *nuevo ;
if(!PerteneceConjuntoAdy(*Primero,dato))
{
nuevo = (ListaAdy*)malloc(sizeof(ListaAdy));
nuevo -> el = dato;
nuevo -> sig = *Primero;
*Primero= nuevo;
}
}

int PertenceVertice(ListaG* Primero, ItemG dato)


{
ListaG *ptr;
for (ptr = Primero; ptr != NULL; ptr = ptr ->sig )
if (ptr-> el.v == dato.v)
return True;
return False;
}

void AnadeVertice(ListaG** Primero, ItemG dato)


{
ListaG *nuevo ;
if(!PertenceVertice(*Primero,dato))
{
nuevo = (ListaG*)malloc(sizeof(ListaG));
nuevo -> el = dato;
nuevo -> sig = *Primero;
*Primero= nuevo;
}
}

void EncuentraPosAdy(ListaAdy *Primero, ItemAdy dato,ListaAdy **Ant,


ListaAdy **Pos)
/* en Ant y Pos retorna la direccióndel nodo anterior y la posición donde se
encuentra. Si no se encontrara, retorna en Pos el valor de NULL*/
{
ListaAdy* ptr, *ant;
int enc = False;
ptr =Primero;
ant = NULL;
while (( ! enc) && (ptr != NULL))
{
enc = (ptr->el.v == dato.v);
if (!enc)
{
ant = ptr;
ptr = ptr -> sig;
}
}
*Ant = ant;
*Pos = ptr;
}

void BorraConjuntoAdy (ListaAdy** Primero, ItemAdy dato)


{
ListaAdy* ptr, *ant;
EncuentraPosAdy(*Primero, dato, &ant, &ptr);
if (ptr != NULL)
{
if (ptr == *Primero)
*Primero = ptr->sig;
else
ant -> sig = ptr->sig;
free(ptr);
}
}

void EncuentraPosGrafo(ListaG *Primero, ItemG dato,ListaG **Ant, ListaG **Pos)


/* en Ant y Pos retorna la direccióndel nodo anterior y la posición donde se
encuentra. Si no se encontrara, retorna en Pos el valor de NULL*/
{
ListaG* ptr, *ant;
int enc = False;
ptr = Primero;
ant = NULL;
while (( ! enc) && (ptr != NULL))
{
enc = (ptr->el.v == dato.v);
if (!enc)
{
ant = ptr;
ptr = ptr -> sig;
}
}
*Ant = ant;
*Pos = ptr;
}
void BorraVertice (ListaG** Primero, ItemG dato)
{
ListaG* ptr, *ant;
ItemAdy dato1;
EncuentraPosGrafo(*Primero, dato, &ant,&ptr);
if (ptr != NULL)
{
if (ptr == *Primero)
*Primero = ptr->sig;
else
ant -> sig = ptr->sig;
BorraListaAdy(&(ptr->el.Ady)); /* borra toda la
deadyacencia*/
free(ptr);
ptr = *Primero;
dato1.v = dato.v;
while (ptr) /*borra todos los arcos que llegan al
vértice v*/
{
BorraConjuntoAdy(&(ptr->el.Ady), dato1);
ptr = ptr->sig;
}
}
}

void BorraListaAdy(ListaAdy ** Primero)


{
ListaAdy *l, *l1;
l = *Primero;
while(l != NULL)
{
l1 = l;
l = l->sig;
free(l1);
}
}

void AnadeArco(ListaG **Primero,Arco arc)


{
ItemG dato;
ItemAdy dato1;
ListaG *Ant,*Pos;
dato.v = arc.u;
dato.Ady = NULL;
AnadeVertice( Primero, dato);
dato.v=arc.v;
AnadeVertice( Primero, dato);
dato.v = arc.u;
EncuentraPosGrafo(*Primero, dato,&Ant,&Pos);
dato1.v = arc.v;
dato1.valor = arc.valor;
AnadeConjuntoAdy(&(Pos->el.Ady), dato1);
}

void BorraArco(ListaG **Primero,Arco arc)


{
ItemG dato;
ItemAdy dato1;
ListaG *Ant,*Pos;
dato.v = arc.u;
dato.Ady = NULL;
EncuentraPosGrafo(*Primero, dato,&Ant,&Pos);
dato1.v = arc.v;
dato1.valor=arc.valor;
BorraConjuntoAdy(&(Pos->el.Ady), dato1);
}

int PertenceArco(ListaG *Primero , Arco arc)


{
ItemG dato;
ItemAdy dato1;
ListaG *Ant,*Pos;
ListaAdy *Ant1, *Pos1;
dato.v = arc.u;
dato.Ady=NULL;
EncuentraPosGrafo(Primero, dato,&Ant,&Pos);
dato1.v = arc.v;
dato1.valor = arc.valor;
if (Pos != NULL)
{
EncuentraPosAdy(Pos->el.Ady,dato1, &Ant1,&Pos1);
return (Pos1 != NULL);
}
return(False);
}

También podría gustarte