冒泡法:
Using directives namespace BubbleSorter { publicclass BubbleSorter { publicvoid Sort(int[] list) { int i, j, temp; bool done =false; j =1; while ((j < list.Length) && (!done)) { done =true; for (i =0; i < list.Length - j; i++) { if (list[i] > list[i +1]) { done =false; temp = list[i]; list[i] = list[i +1]; list[i +1] = temp; } } j++; } } } publicclass MainClass { publicstaticvoid Main() { int[] iArrary =newint[] { 1, 5, 13, 6, 10, 55, 99, 2, 87, 12, 34, 75, 33, 47 }; BubbleSorter sh =new BubbleSorter(); sh.Sort(iArrary); for (int m =0; m < iArrary.Length; m++) Console.Write("{0}", iArrary[m]); Console.WriteLine(); } } }
选择排序法
Using directives namespace SelectionSorter { publicclass SelectionSorter { privateint min; publicvoid Sort(int[] list) { for (int i =0; i < list.Length -1; i++) { min = i; for (int j = i +1; j < list.Length; j++) { if (list[j] < list[min]) min = j; } int t = list[min]; list[min] = list[i]; list[i] = t; } } } publicclass MainClass { publicstaticvoid Main() { int[] iArrary =newint[] { 1, 5, 3, 6, 10, 55, 9, 2, 87, 12, 34, 75, 33, 47 }; SelectionSorter ss =new SelectionSorter(); ss.Sort(iArrary); for (int m =0; m < iArrary.Length; m++) Console.Write("{0}", iArrary[m]); Console.WriteLine(); } } }
插入排序法
Using directives namespace InsertionSorter { publicclass InsetionSorter { publicvoid Sort(int[] list) { for (int i =1; i < list.Length; i++) { int t = list[i]; int j = i; while ((j >0) && (list[j -1] > t)) { list[j] = list[j -1]; --j; } list[j] = t; } } } publicclass MainClass { publicstaticvoid Main() { int[] iArrary =newint[] { 1, 13, 3, 6, 10, 55, 98, 2, 87, 12, 34, 75, 33, 47 }; InsertionSorter ii =new InsertionSorter(); ii.Sort(iArrary); for (int m =0; m < iArrary.Length; m++) Console.Write("{0}", iArrary[m]); Console.WriteLine(); } } }
希尔排序法
Using directives namespace ShellSorter { publicclass ShellSorter { publicvoid Sort(int[] list) { int inc; for (inc =1; inc <= list.Length /9; inc =3* inc +1) ; for (; inc >0; inc /=3) { for (int i = inc +1; i <= list.Length; i += inc) { int t = list[i -1]; int j = i; while ((j > inc) && (list[j - inc -1] > t)) { list[j -1] = list[j - inc -1]; j -= inc; } list[j -1] = t; } } } } publicclass MainClass { publicstaticvoid Main() { int[] iArrary =newint[] { 1, 5, 13, 6, 10, 55, 99, 2, 87, 12, 34, 75, 33, 47 }; ShellSorter sh =new ShellSorter(); sh.Sort(iArrary); for (int m =0; m < iArrary.Length; m++) Console.Write("{0}", iArrary[m]); Console.WriteLine(); } } }
以前空闲的时候用C#实现的路径规划算法,今日贴它出来,看大家有没有更好的实现方案。关于路径规划(最短路径)算法的背景知识,大家可以参考《C++算法--图算法》一书。 该图算法描述的是这样的场景:图由节点和带有方向的边构成,每条边都有相应的权值,路径规划(最短路径)算法就是要找出从节点A到节点B的累积权值最小的路径。 首先,我们可以将“有向边”抽象为Edge类:
publicclass Edge { publicstring StartNodeID ; publicstring EndNodeID ; publicdouble Weight ; //权值,代价 }
节点则抽象成Node类,一个节点上挂着以此节点作为起点的“出边”表。
publicclass Node { privatestring iD ; private ArrayList edgeList ;//Edge的集合--出边表 public Node(string id ) { this.iD = id ; this.edgeList =new ArrayList() ; } #region property publicstring ID { get { returnthis.iD ; } } public ArrayList EdgeList { get { returnthis.edgeList ; } } #endregion }
在计算的过程中,我们需要记录到达每一个节点权值最小的路径,这个抽象可以用PassedPath类来表示:
///<summary> /// PassedPath 用于缓存计算过程中的到达某个节点的权值最小的路径 ///</summary> publicclass PassedPath { privatestring curNodeID ; privatebool beProcessed ; //是否已被处理 privatedouble weight ; //累积的权值 private ArrayList passedIDList ; //路径 public PassedPath(string ID) { this.curNodeID = ID ; this.weight =double.MaxValue ; this.passedIDList =new ArrayList() ; this.beProcessed =false ; }
#region property publicbool BeProcessed { get { returnthis.beProcessed ; } set { this.beProcessed = value ; } }
publicstring CurNodeID { get { returnthis.curNodeID ; } }
publicdouble Weight { get { returnthis.weight ; } set { this.weight = value ; } }
public ArrayList PassedIDList { get { returnthis.passedIDList ; } } #endregion }
#region property publicbool BeProcessed { get { returnthis.beProcessed ; } set { this.beProcessed = value ; } }
publicstring CurNodeID { get { returnthis.curNodeID ; } }
publicdouble Weight { get { returnthis.weight ; } set { this.weight = value ; } }
public ArrayList PassedIDList { get { returnthis.passedIDList ; } } #endregion }
另外,还需要一个表PlanCourse来记录规划的中间结果,即它管理了每一个节点的PassedPath。
///<summary> /// PlanCourse 缓存从源节点到其它任一节点的最小权值路径=》路径表 ///</summary> publicclass PlanCourse { private Hashtable htPassedPath ;
#region ctor public PlanCourse(ArrayList nodeList ,string originID) { this.htPassedPath =new Hashtable() ;
Node originNode =null ; foreach(Node node in nodeList) { if(node.ID == originID) { originNode = node ; } else { PassedPath pPath =new PassedPath(node.ID) ; this.htPassedPath.Add(node.ID ,pPath) ; } }
if(originNode ==null) { thrownew Exception("The origin node is not exist !") ; } this.InitializeWeight(originNode) ; }
privatevoid InitializeWeight(Node originNode) { if((originNode.EdgeList ==null) ||(originNode.EdgeList.Count ==0)) { return ; }
foreach(Edge edge in originNode.EdgeList) { PassedPath pPath =this[edge.EndNodeID] ; if(pPath ==null) { continue ; }
pPath.PassedIDList.Add(originNode.ID) ; pPath.Weight = edge.Weight ; } } #endregion
public PassedPath this[string nodeID] { get { return (PassedPath)this.htPassedPath[nodeID] ; } } }
#region ctor public PlanCourse(ArrayList nodeList ,string originID) { this.htPassedPath =new Hashtable() ;
Node originNode =null ; foreach(Node node in nodeList) { if(node.ID == originID) { originNode = node ; } else { PassedPath pPath =new PassedPath(node.ID) ; this.htPassedPath.Add(node.ID ,pPath) ; } }
if(originNode ==null) { thrownew Exception("The origin node is not exist !") ; } this.InitializeWeight(originNode) ; }
privatevoid InitializeWeight(Node originNode) { if((originNode.EdgeList ==null) ||(originNode.EdgeList.Count ==0)) { return ; }
foreach(Edge edge in originNode.EdgeList) { PassedPath pPath =this[edge.EndNodeID] ; if(pPath ==null) { continue ; }
pPath.PassedIDList.Add(originNode.ID) ; pPath.Weight = edge.Weight ; } } #endregion
public PassedPath this[string nodeID] { get { return (PassedPath)this.htPassedPath[nodeID] ; } } }
在所有的基础构建好后,路径规划算法就很容易实施了,该算法主要步骤如下: (1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的边的权,否则设为double.MaxValue。 (2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点 经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理。 (3)重复(2),直至所有的可达节点都被处理一遍。 (4)从PlanCourse表中获取目的点的PassedPath,即为结果。 下面就来看上述步骤的实现,该实现被封装在RoutePlanner类中:
///<summary> /// RoutePlanner 提供图算法中常用的路径规划功能。 /// 2005.09.06 ///</summary> publicclass RoutePlanner { public RoutePlanner() { }
#region Paln //获取权值最小的路径 public RoutePlanResult Paln(ArrayList nodeList ,string originID ,string destID) { PlanCourse planCourse =new PlanCourse(nodeList ,originID) ;
Node curNode =this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
#region 计算过程 while(curNode !=null) { PassedPath curPath = planCourse[curNode.ID] ; foreach(Edge edge in curNode.EdgeList) { PassedPath targetPath = planCourse[edge.EndNodeID] ; double tempWeight = curPath.Weight + edge.Weight ;
if(tempWeight < targetPath.Weight) { targetPath.Weight = tempWeight ; targetPath.PassedIDList.Clear() ;
for(int i=0 ;i<curPath.PassedIDList.Count ;i++) { targetPath.PassedIDList.Add(curPath.PassedIDList[i].ToString()) ; }
targetPath.PassedIDList.Add(curNode.ID) ; } }
//标志为已处理 planCourse[curNode.ID].BeProcessed =true ; //获取下一个未处理节点 curNode =this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ; } #endregion //表示规划结束 returnthis.GetResult(planCourse ,destID) ; } #endregion
#region private method #region GetResult //从PlanCourse表中取出目标节点的PassedPath,这个PassedPath即是规划结果 private RoutePlanResult GetResult(PlanCourse planCourse ,string destID) { PassedPath pPath = planCourse[destID] ;
if(pPath.Weight ==int.MaxValue) { RoutePlanResult result1 =new RoutePlanResult(null ,int.MaxValue) ; return result1 ; } string[] passedNodeIDs =newstring[pPath.PassedIDList.Count] ; for(int i=0 ;i<passedNodeIDs.Length ;i++) { passedNodeIDs[i] = pPath.PassedIDList[i].ToString() ; } RoutePlanResult result =new RoutePlanResult(passedNodeIDs ,pPath.Weight) ;
return result ; } #endregion
#region GetMinWeightRudeNode //从PlanCourse取出一个当前累积权值最小,并且没有被处理过的节点 private Node GetMinWeightRudeNode(PlanCourse planCourse ,ArrayList nodeList ,string originID) { double weight =double.MaxValue ; Node destNode =null ;
foreach(Node node in nodeList) { if(node.ID == originID) { continue ; }
PassedPath pPath = planCourse[node.ID] ; if(pPath.BeProcessed) { continue ; }
if(pPath.Weight < weight) { weight = pPath.Weight ; destNode = node ; } }
return destNode ; } #endregion #endregion }
#region Paln //获取权值最小的路径 public RoutePlanResult Paln(ArrayList nodeList ,string originID ,string destID) { PlanCourse planCourse =new PlanCourse(nodeList ,originID) ;
Node curNode =this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
#region 计算过程 while(curNode !=null) { PassedPath curPath = planCourse[curNode.ID] ; foreach(Edge edge in curNode.EdgeList) { PassedPath targetPath = planCourse[edge.EndNodeID] ; double tempWeight = curPath.Weight + edge.Weight ;
if(tempWeight < targetPath.Weight) { targetPath.Weight = tempWeight ; targetPath.PassedIDList.Clear() ;
for(int i=0 ;i<curPath.PassedIDList.Count ;i++) { targetPath.PassedIDList.Add(curPath.PassedIDList[i].ToString()) ; }
targetPath.PassedIDList.Add(curNode.ID) ; } }
//标志为已处理 planCourse[curNode.ID].BeProcessed =true ; //获取下一个未处理节点 curNode =this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ; } #endregion //表示规划结束 returnthis.GetResult(planCourse ,destID) ; } #endregion
#region private method #region GetResult //从PlanCourse表中取出目标节点的PassedPath,这个PassedPath即是规划结果 private RoutePlanResult GetResult(PlanCourse planCourse ,string destID) { PassedPath pPath = planCourse[destID] ;
if(pPath.Weight ==int.MaxValue) { RoutePlanResult result1 =new RoutePlanResult(null ,int.MaxValue) ; return result1 ; } string[] passedNodeIDs =newstring[pPath.PassedIDList.Count] ; for(int i=0 ;i<passedNodeIDs.Length ;i++) { passedNodeIDs[i] = pPath.PassedIDList[i].ToString() ; } RoutePlanResult result =new RoutePlanResult(passedNodeIDs ,pPath.Weight) ;
return result ; } #endregion
#region GetMinWeightRudeNode //从PlanCourse取出一个当前累积权值最小,并且没有被处理过的节点 private Node GetMinWeightRudeNode(PlanCourse planCourse ,ArrayList nodeList ,string originID) { double weight =double.MaxValue ; Node destNode =null ;
foreach(Node node in nodeList) { if(node.ID == originID) { continue ; }
PassedPath pPath = planCourse[node.ID] ; if(pPath.BeProcessed) { continue ; }
if(pPath.Weight < weight) { weight = pPath.Weight ; destNode = node ; } }
return destNode ; } #endregion #endregion }