//************************************//
//copiar un nodo existente a otro nodo//
//************************************//
template <typename datonodo_t, typename datoarista_t>
void Grafo<datonodo_t,datoarista_t>::CopiarNodo(pNodo& padre, pNodo& hijo, pArista& precedente, pArista& NuevaArista)
{
if (padre)
{
//eliminamos la posibilidad de tener dos nodos iguales bajo el mismo padre
if (esReferenciaCircular(padre,hijo))
{
std::cout<<"Referencia circular"<<std::endl;
}
else
{
InsertarHijo(padre,hijo, precedente, NuevaArista);
}
}
else std::cout<<"No hay padre al que copiar!!!"<<std::endl;
}
//**********************************************************************//
//recorre sólamente los nodos hijos directos que penden de un nodo padre//
//**********************************************************************//
template <typename datonodo_t, typename datoarista_t>
void Grafo<datonodo_t,datoarista_t>::recorrerHijos(const pNodo& padre, TratarArista& tratamiento)
{
if (padre->adyacente!=0)
{
pArista A=padre->adyacente;
while (A->siguiente!=0)
{
tratamiento(A);
A=A->siguiente;
}
tratamiento(A);
}
}
//*************************************//
//recorrer el arbol a partir de un nodo//
//*************************************//
template <typename datonodo_t, typename datoarista_t>
void Grafo<datonodo_t,datoarista_t>::recorrerGrafo(pNodo& inicio, TratarArista& tratamiento)
{
pArista A;
if (inicio)
{
guardaAristas (inicio);//meto las aristas en la pila
while (!pila.empty())
{
A=pila.top();
pila.pop();
pila.pop();
tratamiento(A);
recorrerGrafo(A->destino,tratamiento);
}
}
}
//****************************************************************************//
//recorrer el arbol a partir de un nodo con informacion del nivel de cada nodo//
//****************************************************************************//
template <typename datonodo_t, typename datoarista_t>
void Grafo<datonodo_t,datoarista_t>::recorrerGrafoConNiveles(pNodo& inicio, TratarAristaConNiveles& tratamiento, int n)
{
pArista A;
if (inicio)
{
guardaAristasNivel(inicio,n);
while (!pilaniveles.empty())
{
A=pilaniveles.top().first;
n=pilaniveles.top().second+1;
pilaniveles.pop();
std::pair<pArista,int>prov;
prov.first=A;
prov.second=n;
tratamiento(prov);
recorrerGrafoConNiveles(A->destino,tratamiento,n);
}
}
}
//***************************************************//
//busca todos los ancestros de un nodo dado //
//***************************************************//
template <typename datonodo_t, typename datoarista_t>
void Grafo<datonodo_t,datoarista_t>::recorrerAncestros(pNodo& n,TratarNodo& tratamiento)
{
std::list<pNodo>listanodos;
typename std::list<pNodo>::iterator it;
pNodo indice=Raiz;
while (indice)
{
if (indice->adyacente)
{
pArista A=indice->adyacente;
while (A)
{
if (A->destino==n)
{
listanodos.push_back(indice);
tratamiento(indice);
//std::cout<<"El nodo "<<indice->datonodo.LeeCodigo()<<" es padre de "<<A->destino->datonodo.LeeCodigo()<<std::endl;
break;
}
else
{
A=A->siguiente;
}
}
}
indice=indice->siguiente;
}
for (it=listanodos.begin(); it!=listanodos.end(); ++it)
{
if (*it!=Raiz)
{
recorrerAncestros(*it, tratamiento);
}
}
}
//*********************************//
//muestra todos los nodos del grafo//
//*********************************//
template <typename datonodo_t, typename datoarista_t>
void Grafo<datonodo_t,datoarista_t>::recorrerNodos(TratarNodo& tratamiento)
{
pNodo indice=Raiz;
while (indice!=0)
{
tratamiento(indice);
indice=indice->siguiente;
}
}
//*********************************************************************//
//busca si un nodo que quiero copiar como hijo de otro es padre de éste//
//necesario para evitar referencias circulares //
//*********************************************************************//
template <typename datonodo_t, typename datoarista_t>
bool Grafo<datonodo_t,datoarista_t>::esReferenciaCircular(pNodo& padre, pNodo& hijo)
{
if (padre==hijo)
{
std::cout<<"Referencia $$ circular"<<std::endl;
return true;
}
else
{
pArista A;
bool encontrado=false;
guardaAristas(hijo);
while (!pila.empty())
{
A=pila.top();
pila.pop();
if (A->destino==padre)
{
//vacio la pila
while (!pila.empty())
pila.pop();
std::cout<<"Referencia circular"<<std::endl;
return true;
}
return encontrado || esReferenciaCircular(padre,A->destino);
}
}
return false;
}