1 class Edge : IComparable
2 {3 public int StartIndex { get; set; }4
5 public int EndIndex { get; set; }6
7 public int Weight { get; set; }8
9 public string Description { get; set; }10
11 public intCompareTo(Edge other)12 {13 return this.Weight.CompareTo(other.Weight);14 }15 }16
17 private class Path : IComparable
18 {19 publicPath()20 {21 this.Edges = new List();22 }23
24 public int StartVertexIndex { get; set; }25
26 public int EndVertexIndex { get; set; }27
28 public List Edges { get; private set; }29
30 public int Weight { get; private set; }31
32 public void AddEdges(IEnumerableedges)33 {34 foreach (var edge inedges)35 {36 this.AddEdge(edge);37 }38 }39
40 public voidAddEdge(Edge edge)41 {42 this.Edges.Add(edge);43 this.Weight +=edge.Weight;44 }45
46 public intCompareTo(Path other)47 {48 return this.Weight.CompareTo(other.Weight);49 }50 }51
52 class Vertex
53 {54 public T Value { get; set; }55 }56
57 class Graph
58 {59 #region 私有字段
60
61 private int_maxSize;62 private Vertex[] _vertexs;63 privateEdge[][] _edges;64 private int _vertexCount = 0;65
66 #endregion
67
68 #region 构造方法
69
70 public Graph(intmaxSize)71 {72 _maxSize =maxSize;73 _vertexs = new Vertex[_maxSize];74 _edges = newEdge[_maxSize][];75 for (var i = 0; i < _maxSize; i++)76 {77 _edges[i] = newEdge[_maxSize];78 }79 }80
81 #endregion
82
83 #region 添加顶点
84
85 public GraphAddVertex(T value)86 {87 _vertexs[_vertexCount++] = new Vertex { Value =value };88
89 return this;90 }91
92 #endregion
93
94 #region 添加边
95
96 public Graph AddUnDirectedEdge(T startItem, T endItem, intweight)97 {98 var startIndex = this.GetVertexIndex(startItem);99 var endIndex = this.GetVertexIndex(endItem);100
101 _edges[startIndex][endIndex] = new Edge { StartIndex = startIndex, EndIndex = endIndex, Weight = weight, Description = String.Format("{0}->{1}", startItem, endItem) };102 _edges[endIndex][startIndex] = new Edge { StartIndex = endIndex, EndIndex = startIndex, Weight = weight, Description = String.Format("{0}->{1}", endItem, startItem) };103
104 return this;105 }106
107 public Graph AddDirectedEdge(T startItem, T endItem, intweight)108 {109 var startIndex = this.GetVertexIndex(startItem);110 var endIndex = this.GetVertexIndex(endItem);111
112 _edges[startIndex][endIndex] = new Edge { StartIndex = startIndex, EndIndex = endIndex, Weight = weight, Description = String.Format("{0}->{1}", startItem, endItem) };113
114 return this;115 }116
117 #endregion
118
119 #region 最小生成树
120
121 public IEnumerableGetMinimumSpanningTree()122 {123 var minimumSpanningTrees = new List();124 Dictionary vertexInTreesTracker = new Dictionary();125 var queue = new PriorityQueue(_maxSize);126
127 var currentVertexIndex = 0;128 while (minimumSpanningTrees.Count < _vertexCount - 1)129 {130 vertexInTreesTracker[currentVertexIndex] = true;131
132 foreach (var item in_edges[currentVertexIndex])133 {134 if (item == null)135 {136 continue;137 }138 if(vertexInTreesTracker.ContainsKey(item.EndIndex))139 {140 continue;141 }142
143 queue.EnQueue(item);144 }145
146 var smallEdge =queue.DeQueue();147 while(vertexInTreesTracker.ContainsKey(smallEdge.EndIndex))148 {149 smallEdge =queue.DeQueue();150 }151 minimumSpanningTrees.Add(smallEdge);152 currentVertexIndex =smallEdge.EndIndex;153 }154
155 returnminimumSpanningTrees;156 }157
158 #endregion
159
160 #region 最短路径
161
162 public IEnumerableGetShortestPath(T startItem, T endItem)163 {164 var startIndex = this.GetVertexIndex(startItem);165 var endIndex = this.GetVertexIndex(endItem);166
167 var shortestPaths = new Dictionary();168 var queue = new PriorityQueue(_maxSize);169
170 var currentVertexIndex =startIndex;171 var currentPath = newPath172 {173 StartVertexIndex =startIndex,174 EndVertexIndex =endIndex175 };176
177 while (!shortestPaths.ContainsKey(endIndex))178 {179 foreach (var item in_edges[currentVertexIndex])180 {181 if (item == null)182 {183 continue;184 }185 if(shortestPaths.ContainsKey(item.EndIndex))186 {187 continue;188 }189
190 var path = newPath191 {192 StartVertexIndex =startIndex,193 EndVertexIndex =item.EndIndex194 };195 path.AddEdges(currentPath.Edges);196 path.AddEdge(item);197 queue.EnQueue(path);198 }199
200 var smallPath =queue.DeQueue();201 while(shortestPaths.ContainsKey(smallPath.EndVertexIndex))202 {203 smallPath =queue.DeQueue();204 }205 shortestPaths[smallPath.EndVertexIndex] =smallPath;206 currentVertexIndex =smallPath.EndVertexIndex;207 currentPath =smallPath;208 }209
210 returnshortestPaths[endIndex].Edges;211 }212
213 #endregion
214
215 #region 帮助方法
216
217 private intGetVertexIndex(T item)218 {219 for (var i = 0; i < _vertexCount; i++)220 {221 if(_vertexs[i].Value.Equals(item))222 {223 returni;224 }225 }226 return -1;227 }228
229 #endregion
230 }