Ai
1 Star 1 Fork 0

AndyZhang/C-Sharp-Algorithms

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
DepthFirstSearcher.cs 5.88 KB
一键复制 编辑 原始数据 按行查看 历史
Ahmad Alhour 提交于 2015-08-23 20:06 +08:00 . BFS Searcher and VFS Shortest Paths bugfixs.
/***
* Implements the Depth-First Search algorithm in two ways: Iterative and Recursive.
*
* Provides multiple functions for traversing graphs:
* 1. PrintAll(),
* 2. VisitAll(Action<T> forEachFunc),
* 3. FindFirstMatch(Predicate<T> match).
*
* The VisitAll() applies a function to every graph node. The FindFirstMatch() function searches the graph for a predicate match.
*/
using System;
using System.Collections.Generic;
using DataStructures.Graphs;
namespace Algorithms.Graphs
{
public static class DepthFirstSearcher
{
/// <summary>
/// DFS Recursive Helper function.
/// Visits the neighbors of a given vertex recusively, and applies the given Action<T> to each one of them.
/// </summary>
private static void _visitNeighbors<T>(T Vertex, ref IGraph<T> Graph, ref Dictionary<T, object> Parents, Action<T> Action) where T : IComparable<T>
{
foreach (var adjacent in Graph.Neighbours(Vertex))
{
if (!Parents.ContainsKey(adjacent))
{
// DFS VISIT NODE
Action(adjacent);
// Save adjacents parent into dictionary
Parents.Add(adjacent, Vertex);
// Recusively visit adjacent nodes
_visitNeighbors(adjacent, ref Graph, ref Parents, Action);
}
}
}
/// <summary>
/// Recursive DFS Implementation with helper.
/// Traverses all the nodes in a graph starting from a specific node, applying the passed action to every node.
/// </summary>
public static void VisitAll<T>(ref IGraph<T> Graph, T StartVertex, Action<T> Action) where T : IComparable<T>
{
// Check if graph is empty
if (Graph.VerticesCount == 0)
throw new Exception("Graph is empty!");
// Check if graph has the starting vertex
if (!Graph.HasVertex(StartVertex))
throw new Exception("Starting vertex doesn't belong to graph.");
var parents = new Dictionary<T, object>(Graph.VerticesCount); // keeps track of visited nodes and tree-edges
foreach (var vertex in Graph.Neighbours(StartVertex))
{
if (!parents.ContainsKey(vertex))
{
// DFS VISIT NODE
Action(vertex);
// Add to parents dictionary
parents.Add(vertex, null);
// Visit neighbors using recusrive helper
_visitNeighbors(vertex, ref Graph, ref parents, Action);
}
}
}
/// <summary>
/// Iterative DFS Implementation.
/// Given a starting node, dfs the graph and print the nodes as they get visited.
/// </summary>
public static void PrintAll<T>(IGraph<T> Graph, T StartVertex) where T : IComparable<T>
{
// Check if graph is empty
if (Graph.VerticesCount == 0)
throw new Exception("Graph is empty!");
// Check if graph has the starting vertex
if (!Graph.HasVertex(StartVertex))
throw new Exception("Starting vertex doesn't belong to graph.");
var visited = new HashSet<T>();
var stack = new Stack<T>(Graph.VerticesCount);
stack.Push(StartVertex);
while (stack.Count > 0)
{
var current = stack.Pop();
if (!visited.Contains(current))
{
// DFS VISIT NODE STEP
Console.Write(String.Format("({0}) ", current));
visited.Add(current);
// Get the adjacent nodes of current
foreach (var adjacent in Graph.Neighbours(current))
if (!visited.Contains(adjacent))
stack.Push(adjacent);
}
}
}
/// <summary>
/// Iterative DFS Implementation.
/// Given a predicate function and a starting node, this function searches the nodes of the graph for a first match.
/// </summary>
public static T FindFirstMatch<T>(IGraph<T> Graph, T StartVertex, Predicate<T> Match) where T : IComparable<T>
{
// Check if graph is empty
if (Graph.VerticesCount == 0)
throw new Exception("Graph is empty!");
// Check if graph has the starting vertex
if (!Graph.HasVertex(StartVertex))
throw new Exception("Starting vertex doesn't belong to graph.");
var stack = new Stack<T>();
var parents = new Dictionary<T, object>(Graph.VerticesCount); // keeps track of visited nodes and tree-edges
object currentParent = null;
stack.Push(StartVertex);
while (stack.Count > 0)
{
var current = stack.Pop();
// Skip loop if node was already visited
if (!parents.ContainsKey(current))
{
// Save its parent into the dictionary
// Mark it as visited
parents.Add(current, currentParent);
// DFS VISIT NODE STEP
if (Match(current))
return current;
// Get currents adjacent nodes (might add already visited nodes).
foreach (var adjacent in Graph.Neighbours(current))
if (!parents.ContainsKey(adjacent))
stack.Push(adjacent);
// Mark current as the father of its adjacents. This helps keep track of tree-nodes.
currentParent = current;
}
}//end-while
throw new Exception("Item was not found!");
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C#
1
https://gitee.com/strongandyzhang/C-Sharp-Algorithms.git
git@gitee.com:strongandyzhang/C-Sharp-Algorithms.git
strongandyzhang
C-Sharp-Algorithms
C-Sharp-Algorithms
master

搜索帮助