以邻接表为存储结构的---图的算法实现
来源:互联网 发布:minecraft mac forge 编辑:程序博客网 时间:2024/06/04 17:55
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- namespace HBDiscover
- {
- public class AdjacencyList<T>
- {
- List<Vertex<T>> items;
- public bool IsCycle;
- public AdjacencyList() : this(10) { }
- public AdjacencyList(int capacity)
- {
- items = new List<Vertex<T>>(capacity);
- }
- public void AddVertex(T item)
- {
- if (Contains(item))
- {
- throw new ArgumentException("插入了重复顶点!");
- }
- items.Add(new Vertex<T>(item));
- }
- public void AddVertex(params T[] vexs)
- {
- foreach (T temp in vexs)
- {
- AddVertex(temp);
- }
- }
- public void AddEdge(T from, T to, int weight)
- {
- Vertex<T> fromVer = Find(from);
- if (fromVer == null)
- {
- throw new ArgumentException("头顶点并不存在!");
- }
- Vertex<T> toVer = Find(to);
- if (toVer == null)
- {
- throw new ArgumentException("尾顶点并不存在!");
- }
-
- AddDirectedEdge(fromVer, toVer, weight);
- AddDirectedEdge(toVer, fromVer, weight);
- }
- public void AddEdge(T from, T to)
- {
- AddEdge(from, to, 0);
- }
- public void AddDirectedEdge(T from, T to, int weight)
- {
- Vertex<T> fromVer = Find(from);
- if (fromVer == null)
- {
- throw new ArgumentException("头顶点并不存在!");
- }
- Vertex<T> toVer = Find(to);
- if (toVer == null)
- {
- throw new ArgumentException("尾顶点并不存在!");
- }
- AddDirectedEdge(fromVer, toVer, weight);
- }
- public void AddDirectedEdge(T from, T to)
- {
- AddDirectedEdge(from, to, 0);
- }
- public bool Contains(T item)
- {
- return Find(item) != null;
- }
- private Vertex<T> Find(T item)
- {
- foreach (Vertex<T> v in items)
- {
- if (v.data.Equals(item))
- {
- return v;
- }
- }
- return null;
- }
-
- private void AddDirectedEdge(Vertex<T> fromVer, Vertex<T> toVer,int weight)
- {
- if (fromVer.firstEdge == null)
- {
- fromVer.firstEdge = new Edge(fromVer,toVer, weight);
- }
- else
- {
- Edge edge = fromVer.firstEdge;
- while(edge.next!=null)
- {
-
- if (edge.adjvex.data.Equals(toVer.data))
- {
- throw new ArgumentException("添加了重复的边!");
- }
- edge = edge.next;
- }
- edge.next = new Edge(fromVer, toVer, weight);
-
-
-
-
-
-
-
-
-
-
-
- }
- fromVer.OutDegree += 1;
- toVer.InDegree += 1;
- }
-
- private void AddDirectedEdge(Vertex<T> fromVer, Vertex<T> toVer)
- {
- AddDirectedEdge(fromVer, toVer,0);
- }
- public override string ToString()
- {
- string s = string.Empty;
- foreach (Vertex<T> v in items)
- {
- s += v.data.ToString() + ":";
- if (v.firstEdge != null)
- {
- Edge tmp = v.firstEdge;
- while (tmp != null)
- {
- s += tmp.adjvex.data.ToString();
- tmp = tmp.next;
- }
- }
- s += "/r/n";
- }
- return s;
- }
-
- [Serializable()]
- public class Edge : IComparable<Edge>
- {
- public Vertex<T> adjvex;
- public Vertex<T> parentVex;
- public Edge next;
- public int Wegit;
- public Edge(Vertex<T> value)
- {
- adjvex = value;
- }
- public Edge(Vertex<T> _parentVex, Vertex<T> _adjvex, int weight)
- {
- Wegit = weight;
- adjvex = _adjvex;
- parentVex = _parentVex;
- }
- public int CompareTo(Edge other)
- {
- return Wegit.CompareTo(other.Wegit);
- }
- }
-
- [Serializable()]
- public class Vertex<TValue>
- {
- public TValue data;
- public Edge firstEdge;
- public Boolean visited;
- public int InDegree;
- public int OutDegree;
- public Vertex(TValue value)
- {
- data = value;
- }
-
- public void ClearEdges()
- {
- Edge edge = this.firstEdge;
- while (edge != null)
- {
- edge.adjvex.InDegree -= 1;
- edge=edge.next;
- }
- this.firstEdge = null;
- }
- }
-
-
-
-
-
-
-
- private void DepthSearch(Vertex<T> vex,System.Text.StringBuilder strBuilder)
- {
- strBuilder.Append(Convert.ToString(vex.data));
- vex.visited = true;
- Edge edge = vex.firstEdge;
- while (edge!=null)
- {
- if(!edge.adjvex.visited)
- DepthSearch(edge.adjvex, strBuilder);
- edge = edge.next;
- }
- }
- public string DepthSearch()
- {
- return DepthSearch(this.items[0]);
- }
- public string DepthSearch(Vertex<T> vex)
- {
- System.Text.StringBuilder strBuilder = new System.Text.StringBuilder();
- DepthSearch(vex, strBuilder);
- return strBuilder.ToString();
- }
-
-
-
-
-
-
- private void BreadthSearch(Vertex<T> vex, System.Text.StringBuilder strBuilder)
- {
- Queue<Vertex<T>> queue = new Queue<Vertex<T>>();
- queue.Enqueue(vex);
- vex.visited = true;
- strBuilder.Append(vex.data.ToString());
- while (queue.Count > 0)
- {
- Edge edge = queue.Dequeue().firstEdge;
- while(edge != null)
- {
- Vertex<T> tempVex = edge.adjvex;
- if (!tempVex.visited)
- {
- queue.Enqueue(tempVex);
- tempVex.visited = true;
- strBuilder.Append(tempVex.data.ToString());
- }
- edge = edge.next;
- }
- }
- }
- public string BreadthSearch(Vertex<T> vex)
- {
- System.Text.StringBuilder strBuilder = new System.Text.StringBuilder();
- BreadthSearch(vex, strBuilder);
- return strBuilder.ToString();
- }
- public string BreadthSearch()
- {
- return BreadthSearch(this.items[0]);
- }
- public void ResetVisitedStatus()
- {
- foreach (Vertex<T> vex in this.items)
- {
- vex.visited = false;
- }
- }
-
- public string GetMstByKruskal()
- {
- string strValue = string.Empty;
- List<Edge> list = new List<Edge>();
- foreach (Vertex<T> vex in this.items)
- {
- Edge edge = vex.firstEdge;
- vex.visited = true;
- while (edge != null)
- {
- if(edge.adjvex!=null && !edge.adjvex.visited)
- list.Add(edge);
- edge = edge.next;
- }
- }
- list.Sort();
- ResetVisitedStatus();
- int i, k;
- for (i=0,k=0;i<list.Count && k<this.items.Count-1;i++)
- {
- Edge edge = list[i];
- if (edge.adjvex.visited)
- continue;
- strValue += edge.parentVex.data.ToString() + ":" + edge.adjvex.data.ToString()+"|";
- k++;
- }
- return strValue;
- }
- public string GetMstByPrim()
- {
- List<Vertex<T>> vexList = new List<Vertex<T>>();
-
- Vertex<T> minEdgeParentVex = this.items[0];
- List<Edge> edgeList = new List<Edge>();
- string strValue = string.Empty;
- vexList.Add(this.items[0]);
- while (vexList.Count < this.items.Count)
- {
- Edge minEdge = null;
-
- foreach (Vertex<T> vex in vexList)
- {
- Edge edge = vex.firstEdge;
- while (edge != null)
- {
- if (!edge.adjvex.visited)
- {
- if (minEdge == null)
- {
- minEdge = edge;
- minEdgeParentVex = vex;
- }
- else
- {
- if (edge.Wegit < minEdge.Wegit)
- {
- minEdge = edge;
- minEdgeParentVex = vex;
- }
- }
- }
- edge = edge.next;
- }
- }
- minEdgeParentVex.visited = true;
- minEdge.adjvex.visited = true;
- edgeList.Add(minEdge);
- vexList.Add(minEdge.adjvex);
- strValue += minEdge.parentVex.data + ":" + minEdge.adjvex.data.ToString() + "|";
- }
- return strValue;
- }
-
- private class PassedPathInfo
- {
- public int Weight;
- public List<T> PassedVertexs;
- public PassedPathInfo(int _Weight,T firstPath)
- {
- Weight = _Weight;
- PassedVertexs = new List<T>();
- PassedVertexs.Add(firstPath);
- }
- public PassedPathInfo(int _Weight,List<T> list)
- {
- Weight = _Weight;
- PassedVertexs = list;
- }
- public void ClearPath()
- {
- PassedVertexs.Clear();
- }
- public void AddWeight(int _Weight)
- {
- Weight += _Weight;
- }
- public void AddPath(T path)
- {
- PassedVertexs.Add(path);
- }
- }
-
-
-
-
-
-
- public string GetMinPath(T originVertex,T destVertex)
- {
- if(originVertex.Equals(destVertex))
- throw new Exception("起始顶点不能是目标定顶");
- Vertex<T> originVex = this.Find(originVertex);
- Vertex<T> destVex = this.Find(destVertex);
- if (originVex == null || destVex == null)
- {
- throw new Exception("起始顶点或目标定顶未找到");
- }
- Dictionary<T, PassedPathInfo> vexPssedPaths = new Dictionary<T, PassedPathInfo>();
- RecursiveFindMinPath(vexPssedPaths, originVex);
- if (!vexPssedPaths.ContainsKey(destVertex))
- throw new Exception("起始顶点不能到达目标顶点");
-
- string strValue = string.Empty;
- Dictionary<T, PassedPathInfo>.Enumerator e = vexPssedPaths.GetEnumerator();
- while (e.MoveNext())
- {
- strValue += e.Current.Key + ":"+e.Current.Value.Weight.ToString()+"|";
- if (e.Current.Value.PassedVertexs != null)
- {
- foreach (T vexStr in e.Current.Value.PassedVertexs)
- {
- strValue += "-->";
- strValue += vexStr;
- }
- }
- else
- {
- strValue += "无路径";
- }
- strValue += "/r/n";
- }
- return strValue;
- }
-
- private void RecursiveFindMinPath(Dictionary<T, PassedPathInfo> vexPssedPaths, Vertex<T> originVex)
- {
- Edge edge = originVex.firstEdge;
- while (edge != null)
- {
- if (edge.adjvex.visited)
- {
- edge = edge.next;
- continue;
- }
-
- bool bParentVexVisited = vexPssedPaths.ContainsKey(edge.parentVex.data);
-
- bool bChildVexVisited = vexPssedPaths.ContainsKey(edge.adjvex.data);
-
- PassedPathInfo childPassedPath = bChildVexVisited ? vexPssedPaths[edge.adjvex.data] : null;
-
- PassedPathInfo parentPassedPath = bParentVexVisited ? vexPssedPaths[edge.parentVex.data] : null;
-
- List<T> parentPathListCopy = bParentVexVisited ? new List<T>(parentPassedPath.PassedVertexs) ?? null:null;
-
-
- if (!bChildVexVisited)
- {
-
- if (!bParentVexVisited)
- {
- List<T> list = new List<T>() { edge.parentVex.data, edge.adjvex.data };
- vexPssedPaths.Add(edge.adjvex.data, new PassedPathInfo(edge.Wegit, list));
- }
- else
- {
-
- parentPathListCopy.Add(edge.adjvex.data);
- vexPssedPaths.Add(edge.adjvex.data, new PassedPathInfo(parentPassedPath.Weight + edge.Wegit,parentPathListCopy));
- }
- }
- else
- {
- if (!bParentVexVisited)
- {
- if (edge.Wegit < childPassedPath.Weight)
- {
- parentPathListCopy.Add(edge.adjvex.data);
- childPassedPath.Weight = parentPassedPath.Weight + edge.Wegit;
- childPassedPath.PassedVertexs = parentPathListCopy;
- }
- }
- else
- {
- int temp = parentPassedPath.Weight + edge.Wegit;
- if (temp < childPassedPath.Weight)
- {
- parentPathListCopy.Add(edge.adjvex.data);
- childPassedPath.Weight = temp;
- childPassedPath.PassedVertexs = parentPathListCopy;
- }
- }
- }
- edge = edge.next;
- }
- originVex.visited = true;
-
- Dictionary<T, PassedPathInfo>.Enumerator e = vexPssedPaths.GetEnumerator();
- Vertex<T> vex=null;
- int minWeight = int.MaxValue;
- while (e.MoveNext())
- {
- Vertex<T> temp = this.Find(e.Current.Key);
- if (!temp.visited && e.Current.Value.Weight < minWeight)
- {
- minWeight = e.Current.Value.Weight;
- vex = temp;
- }
- }
- if (vex != null)
- RecursiveFindMinPath(vexPssedPaths, vex);
- }
-
- public string TopologicalSort()
- {
- if (this.IsCycle)
- return "此图是一个环";
- List<Vertex<T>> deepCopyVexList = (List<Vertex<T>>)HBDiscover.Utility
- .CloneHelpers.DeepClone(this.items);
- string strResult = string.Empty;
- List<Vertex<T>> topoVexList = new List<AdjacencyList<T>.Vertex<T>>();
- while (topoVexList.Count < this.items.Count)
- {
- foreach (Vertex<T> tempVex in deepCopyVexList)
- {
- if (!tempVex.visited && tempVex.InDegree <= 0)
- {
- tempVex.ClearEdges();
- topoVexList.Add(tempVex);
- strResult += tempVex.data.ToString();
- tempVex.visited = true;
- }
- }
- }
- return strResult;
- }
- }
- }