2017-05-14 2 views
2

L'algorithme C# suivant que j'ai écrit détecte l'existence d'un cycle dans un graphique non orienté en temps O (n). Il évite la récursion et profite du hachage via les Dictionnaires et les HashSets. Mais y a-t-il un moyen de faire mieux?Est-ce le meilleur algorithme pour détecter un cycle dans un graphe non orienté?

void Main() 
{ 
    var graph = new Dictionary<int, HashSet<int>> 
    { 
     { 0, new HashSet<int> { 4 } }, 
     { 1, new HashSet<int> { 2, 3, 4 } }, 
     { 2, new HashSet<int> { 1 } }, 
     { 3, new HashSet<int> { 1, 4 } }, 
     { 4, new HashSet<int> { 0, 1, 3 } } 
    }; 

    Console.WriteLine(HasCycle(graph, 0)); 
} 

bool HasCycle(Dictionary<int, HashSet<int>> graph, int start) 
{ 
    var stack = new Stack<int>(); 
    var visited = new HashSet<int>(); 
    stack.Push(start); 
    var curr = start; 
    var prev = -1; 
    while (stack.Count > 0) 
    { 
     prev = curr; 
     curr = stack.Pop(); 
     visited.Add(curr); 
     HashSet<int> neighbors; 
     if (graph.TryGetValue(curr, out neighbors) && neighbors != null) 
     { 
      foreach (var neighbor in neighbors) 
      { 
       if (!visited.Contains(neighbor)) 
       { 
        stack.Push(neighbor); 
       } 
       else if (neighbor != prev && neighbors.Contains(prev)) 
       { 
        return true; 
       } 
      } 
     } 
    } 
    return false; 
} 
+0

Vous avez un cycle si, en itérant, vous vous retrouvez dans un noeud déjà visité. – arboreal84

+0

Mais pour un graphe * non orienté *, vous devez vous assurer que le noeud déjà visité n'est pas le noeud dont vous venez d'arriver. C'est la logique que je tente de capturer dans mon 'else'. –

Répondre