ventajas usar son recursión recursivos recursivo recursividad recursivas recursiva logica las juego iterativo iterativa iteración funciones ejemplos desventajas cuáles algoritmos c++ algorithm graph depth-first-search traversal

c++ - usar - logica recursiva e iterativa



IFS iterativos vs DFS recursivo y orden de elementos diferentes (2)

A continuación se muestra el código de muestra (según @amit answer anterior) en C # para Adjacency Matrix.

using System; using System.Collections.Generic; namespace GraphAdjMatrixDemo { public class Program { public static void Main(string[] args) { // 0 1 2 3 4 5 6 int[,] matrix = { {0, 1, 1, 0, 0, 0, 0}, {1, 0, 0, 1, 1, 1, 0}, {1, 0, 0, 0, 0, 0, 1}, {0, 1, 0, 0, 0, 0, 1}, {0, 1, 0, 0, 0, 0, 1}, {0, 1, 0, 0, 0, 0 ,0}, {0, 0, 1, 1, 1, 0, 0} }; bool[] visitMatrix = new bool[matrix.GetLength(0)]; Program ghDemo = new Program(); for (int lpRCnt = 0; lpRCnt < matrix.GetLength(0); lpRCnt++) { for (int lpCCnt = 0; lpCCnt < matrix.GetLength(1); lpCCnt++) { Console.Write(string.Format(" {0} ", matrix[lpRCnt, lpCCnt])); } Console.WriteLine(); } Console.Write("/nDFS Recursive : "); ghDemo.DftRecursive(matrix, visitMatrix, 0); Console.Write("/nDFS Iterative : "); ghDemo.DftIterative(matrix, 0); Console.Read(); } //==================================================================================================================================== public void DftRecursive(int[,] srcMatrix, bool[] visitMatrix, int vertex) { visitMatrix[vertex] = true; Console.Write(vertex + " "); for (int neighbour = 0; neighbour < srcMatrix.GetLength(0); neighbour++) { if (visitMatrix[neighbour] == false && srcMatrix[vertex, neighbour] == 1) { DftRecursive(srcMatrix, visitMatrix, neighbour); } } } public void DftIterative(int[,] srcMatrix, int srcVertex) { bool[] visited = new bool[srcMatrix.GetLength(0)]; Stack<int> vertexStack = new Stack<int>(); vertexStack.Push(srcVertex); while (vertexStack.Count > 0) { int vertex = vertexStack.Pop(); if (visited[vertex]) continue; Console.Write(vertex + " "); visited[vertex] = true; for (int neighbour = srcMatrix.GetLength(0) - 1; neighbour >= 0; neighbour--) //for (int neighbour = 0; neighbour < srcMatrix.GetLength(0); neighbour++) { if (srcMatrix[vertex, neighbour] == 1 && visited[neighbour] == false) { vertexStack.Push(neighbour); } } } } } }

He escrito un algoritmo DFS recursivo para recorrer un gráfico:

void Graph<E, N>::DFS(Node n) { std::cout << ReadNode(n) << " "; MarkVisited(n); NodeList adjnodes = Adjacent(n); NodeList::position pos = adjnodes.FirstPosition(); while(!adjnodes.End(pos)) { Node adj = adjnodes.ReadList(pos); if(!IsMarked(adj)) DFS(adj); pos = adjnodes.NextPosition(pos); } }

Luego escribí un algoritmo DFS iterativo usando una pila:

template <typename E, typename N> void Graph<E, N>::IterativeDFS(Node n) { Stack<Node> stack; stack.Push(n); while(!stack.IsEmpty()) { Node u = stack.Read(); stack.Pop(); if(!IsMarked(u)) { std::cout << ReadNode(u) << " "; MarkVisited(u); NodeList adjnodes = Adjacent(u); NodeList::position pos = adjnodes.FirstPosition(); while(!adjnodes.End(pos)) { stack.Push(adjnodes.ReadList(pos)); pos = adjnodes.NextPosition(pos); } } }

Mi problema es que en un gráfico en el que, por ejemplo, ingreso los tres nodos ''a'', ''b'', ''c'' con arcos (''a'', ''b'') y (''a'', ''c'') mi salida es:

''a'', ''b'', ''c'' con la versión recursiva DFS, y:

''a'', ''c'', ''b'' con el iterativo DFS uno.

¿Cómo podría obtener el mismo pedido? ¿Estoy haciendo algo mal?

¡Gracias!


Ambos son algoritmos DFS válidos . Un DFS no especifica qué nodo verá primero. No es importante porque el orden entre los bordes no está definido [recuerde: los bordes son un conjunto generalmente]. La diferencia se debe a la forma en que manejas los hijos de cada nodo.

En el enfoque iterativo: Primero inserta todos los elementos en la pila y luego maneja la cabeza de la pila [que es el último nodo insertado], por lo tanto, el primer nodo que maneja es el último hijo .

En el enfoque recursivo : manejas cada nodo cuando lo ves. Por lo tanto, el primer nodo que maneja es el primer hijo .

Para hacer que el DFS iterativo produzca el mismo resultado que el recursivo, debe agregar elementos a la pila en orden inverso [para cada nodo, inserte su último hijo primero y su primer hijo último]