c#实现图的拓扑排序、深度优先、广度优先两种算法

原文链接:https://blog.csdn.net/MfuuJava/article/details/132933517

拓扑排序是一种在有向无环图(DAG)中对节点进行排序的算法。

在 C# 中,我们可以使用深度优先搜索(DFS)和拓扑排序算法来解决这个问题。

深度优先代码:

using System;
using System.Collections.Generic;

class Graph
{
    private int V; // 图中节点的数量
    private List<List<int>> adj; // 邻接列表

    // 构造函数
    public Graph(int v)
    {
        V = v;
        adj = new List<List<int>>(v);
        for (int i = 0; i < v; ++i)
            adj.Add(new List<int>());
    }

    // 添加边
    public void AddEdge(int v, int w)
    {
        adj[v].Add(w);
    }

    // 拓扑排序的辅助函数
    private void TopologicalSortUtil(int v, bool[] visited, Stack<int> stack)
    {
        visited[v] = true;

        foreach (int i in adj[v])
        {
            if (!visited[i])
                TopologicalSortUtil(i, visited, stack);
        }

        stack.Push(v);
    }

    // 执行拓扑排序
    public void TopologicalSort()
    {
        Stack<int> stack = new Stack<int>();

        bool[] visited = new bool[V];
        for (int i = 0; i < V; i++)
            visited[i] = false;

        for (int i = 0; i < V; i++)
        {
            if (visited[i] == false)
                TopologicalSortUtil(i, visited, stack);
        }

        // 打印排序结果
        while (stack.Count > 0)
        {
            Console.Write(stack.Pop() + " ");
        }
    }

    // 测试
    public static void Main(string[] args)
    {
        Graph graph = new Graph(6);
        graph.AddEdge(5, 2);
        graph.AddEdge(5, 0);
        graph.AddEdge(4, 0);
        graph.AddEdge(4, 1);
        graph.AddEdge(2, 3);
        graph.AddEdge(3, 1);

        Console.WriteLine("拓扑排序结果:");
        graph.TopologicalSort();
        Console.ReadKey();
    }
}

 

在上述代码中,我们首先定义了一个 Graph 类,用于表示有向无环图。Graph 类包含了图中节点的数量和一个邻接列表 adj,用于存储图的边。

我们使用 AddEdge 方法向图中添加边。然后,在 TopologicalSortUtil 方法中,我们使用搜索来遍历图,并将访问过的节点压入栈中。

最后,在 TopologicalSort 方法中,我们遍历图中的所有节点,并调用 TopologicalSortUtil 方法进行拓扑排序。最终,我们打印栈中的元素,即可得到拓扑排序的结果。

在上述示例中,我们创建了一个包含6个节点的图,并添加了一些边。然后,我们执行拓扑排序,并打印排序结果。

 

广度优先:

using System;
using System.Collections.Generic;
public class Graph
{
    private int V; //图中节点的个数
    private List<int>[] adj; //图的邻接表
    public Graph(int v)
    {
        V = v;
        adj = new List<int>[v];
        for (int i = 0; i < v; ++i)
            adj[i] = new List<int>();
    }

    public void AddEdge(int v, int w)

    {
        adj[v].Add(w); //将节点w加入节点v的邻接表中
    }

    public void TopologicalSort()

    {
        int[] indegree = new int[V]; //用于统计每个节点的入度
        for (int i = 0; i < V; ++i)
            indegree[i] = 0;    //统计每个节点的入度

        for (int v = 0; v < V; ++v)
        {
            List<int> adjList = adj[v];
            foreach (int w in adjList)
                indegree[w]++;
        }
        Queue<int> queue = new Queue<int>(); //存放入度为0的节点
        for (int i = 0; i < V; ++i)
        {
            if (indegree[i] == 0)
                queue.Enqueue(i);
        }

        List<int> result = new List<int>(); //存放排序结果

        int count = 0; //已经排序的节点个数

        while (queue.Count > 0)
        {
            int v = queue.Dequeue();
            result.Add(v);
            count++;           //将与节点v相邻的节点的入度减1
            List<int> adjList = adj[v];
            foreach (int w in adjList)
            {
                indegree[w]--;
                if (indegree[w] == 0)
                    queue.Enqueue(w);
            }
        }
        //判断是否有环
        if (count != V)
        {
            Console.WriteLine("图中存在环!");
            return;
        }
        //输出排序结果
        Console.WriteLine("拓扑排序结果:");
        foreach (int v in result)
        {
            Console.Write(v + " ");
        }
    }
}

public class Program

{
    public static void Main(string[] args)
    {
        Graph g = new Graph(6);
        g.AddEdge(5, 2);
        g.AddEdge(5, 0);
        g.AddEdge(4, 0);
        g.AddEdge(4, 1);
        g.AddEdge(2, 3);
        g.AddEdge(3, 1);
        g.TopologicalSort();
        Console.ReadKey();
    }
}

  

using System;
using System.Collections.Generic;
 
public class TopologicalSort
{
    private Dictionary<char, HashSet<char>> graph;
    private Dictionary<char, int> inDegrees;
 
    public TopologicalSort(Dictionary<char, HashSet<char>> graph)
    {
        this.graph = graph;
        inDegrees = new Dictionary<char, int>();
        foreach (var vertex in graph.Keys)
        {
            if (!inDegrees.ContainsKey(vertex))
            {
                inDegrees[vertex] = 0;
            }
            foreach (var neighbor in graph[vertex])
            {
                if (!inDegrees.ContainsKey(neighbor))
                {
                    inDegrees[neighbor] = 0;
                }
                inDegrees[neighbor]++;
            }
        }
    }
 
    public List<char> Sort()
    {
        Queue<char> sources = new Queue<char>();
        List<char> sorted = new List<char>();
 
        foreach (var vertex in inDegrees.Keys)
        {
            if (inDegrees[vertex] == 0)
            {
                sources.Enqueue(vertex);
            }
        }
 
        while (sources.Count > 0)
        {
            char vertex = sources.Dequeue();
            sorted.Add(vertex);
            foreach (var neighbor in graph[vertex])
            {
                inDegrees[neighbor]--;
                if (inDegrees[neighbor] == 0)
                {
                    sources.Enqueue(neighbor);
                }
            }
        }
 
        if (sorted.Count != inDegrees.Count)
        {
            throw new InvalidOperationException("Graph has a cycle");
        }
 
        return sorted;
    }
}
 
// 使用示例
public class Program
{
    public static void Main()
    {
        var graph = new Dictionary<char, HashSet<char>>()
        {
            { 'A', new HashSet<char>() { 'B', 'C' } },
            { 'B', new HashSet<char>() { 'D', 'E' } },
            { 'C', new HashSet<char>() { 'F' } },
            { 'D', new HashSet<char>() { 'E' } },
            { 'E', new HashSet<char>() { 'F' } },
            { 'F', new HashSet<char>() { } }
        };
 
        TopologicalSort topologicalSort = new TopologicalSort(graph);
        List<char> sorted = topologicalSort.Sort();
 
        foreach (char vertex in sorted)
        {
            Console.WriteLine(vertex);
        }
    }
}

  

posted @ 2024-03-20 21:56  yinghualeihenmei  阅读(32)  评论(0编辑  收藏  举报