代码实现
Program.cs
using System;
namespace Csharp_test
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
MyList mylist = new MyList();
mylist.addNode("a");
mylist.addNode("b");
mylist.addNode("c");
mylist.addNode("d");
mylist.addNode("e");
mylist.addEdge("a", new string[] {"b","c"});
mylist.addEdge("b", new string[] {"c" });
mylist.addEdge("c", new string[] {"d" });
mylist.addEdge("d", new string[] {"e" });
mylist.addEdge("e", new string[] {"a" });
bool flag = mylist.topologicalSort();
Console.WriteLine(flag ? "无环" : "有环");
}
}
}
MyList.cs
using System.Collections.Generic;
namespace Csharp_test
{
class MyList
{
/// <summary>
/// 顶点字符串名称-编号字典
/// </summary>
private Dictionary<string, int> noteIntDictionary = new Dictionary<string, int>();
private Dictionary<int, string> noteStringDictionary = new Dictionary<int, string>();
private static int[] emptyIntArray = { }; // 空Int数组
private int cnt = 0; // 顶点编号
/// <summary>
/// 顶点入度数
/// </summary>
private List<int> inDegree = new List<int>();
/// <summary>
/// 顶点边集合
/// 数组下标为顶点编号,对应内容是顶点的出度连接编号
/// </summary>
private List<int[]> edge = new List<int[]>();
/// <summary>
/// 最长路径
/// </summary>
private List<int> dist = new List<int>();
/// <summary>
/// 添加顶点
/// </summary>
/// <param name="nodeName">顶点字符串</param>
/// <returns>
/// true: 顶点添加成功
/// false: 顶点编号重复
/// </returns>
public bool addNode(string nodeName)
{
if (noteIntDictionary.ContainsKey(nodeName) == false)
{
// 加入节点字典
noteIntDictionary.Add(nodeName, cnt);
noteStringDictionary.Add(cnt, nodeName);
inDegree.Add(0);
dist.Add(0);
edge.Add(emptyIntArray);
cnt++;
return true;
}
return false;
}
/// <summary>
/// 为网络各顶点添加有向边,将终点转为数字编号
/// </summary>
/// <param name="nodeName">顶点字符串</param>
/// <param name="nodeOutDegree">顶点出度数组</param>
/// <returns></returns>
public bool addEdge(string nodeName, string[] nodeOutDegree)
{
// 判断字典中是否含有该顶点
if (noteIntDictionary.ContainsKey(nodeName) == true)
{
// 顶点字符串转为编号
int nodeNum = noteIntDictionary[nodeName];
int tempNum = edge[nodeNum].Length;
int[] edgeNum = new int[tempNum + nodeOutDegree.Length];
if (tempNum > 0)
{
edge[nodeNum].CopyTo(edgeNum, 0);
}
for (int i = tempNum; i < nodeOutDegree.Length; i++)
{
string nodeOutDegree_temp = nodeOutDegree[i];
// 判断字典中是否含有该节点
if (noteIntDictionary.ContainsKey(nodeOutDegree_temp) == false)
{
return false;
}
// 顶点添加出度编号
int nodeOutDegreeNum_temp = noteIntDictionary[nodeOutDegree_temp];
inDegree[nodeOutDegreeNum_temp]++;
edgeNum[i] = nodeOutDegreeNum_temp;
}
edge[nodeNum] = edgeNum;
return true;
}
return false;
}
/// <summary>
/// 拓扑排序
/// </summary>
/// <returns>
/// true: 无环
/// false: 有环
/// </returns>
public bool topologicalSort()
{
Queue<int> zeroNode = new Queue<int>();
List<int> inDegree_temp = new List<int>(inDegree);
for (int i=0; i <cnt;++i)
{
if(inDegree_temp[i] == 0)
{
zeroNode.Enqueue(i);
}
}
int count = 0;
while(zeroNode.Count != 0)
{
// TODO: 可能会出现异常
int index = zeroNode.Dequeue();
++count;
foreach(int nodeNum_temp in edge[index])
{
--inDegree_temp[nodeNum_temp];
if(inDegree_temp[nodeNum_temp] == 0)
{
zeroNode.Enqueue(nodeNum_temp);
}
}
}
return count == cnt;
}
}
}