冒泡法:
Using directives
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace
BubbleSorter
{
public class BubbleSorter
{
public void 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++;
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary = new int[] { 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
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace
SelectionSorter
{
public class SelectionSorter
{
private int min;
public void 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;
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary = new int[] { 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
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace
InsertionSorter
{
public class InsetionSorter
{
public void 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;
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary = new int[] { 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
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace
ShellSorter
{
public class ShellSorter
{
public void 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;
}
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary = new int[] { 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类:
public
class
Edge
{
public
string
StartNodeID ;
public
string
EndNodeID ;
public
double
Weight ;
//
权值,代价
}
节点则抽象成Node类,一个节点上挂着以此节点作为起点的“出边”表。
public
class
Node
{
private string iD ;
private ArrayList edgeList ;//Edge的集合--出边表
public Node(string id )
{
this.iD = id ;
this.edgeList = new ArrayList() ;
}
property#region property
public string ID
{
get
{
return this.iD ;
}
}
public ArrayList EdgeList
{
get
{
return this.edgeList ;
}
}
#endregion
}
在计算的过程中,我们需要记录到达每一个节点权值最小的路径,这个抽象可以用PassedPath类来表示:
///
<summary>
///
PassedPath 用于缓存计算过程中的到达某个节点的权值最小的路径
///
</summary>
public
class
PassedPath
{
private
string
curNodeID ;
private
bool
beProcessed ;
//
是否已被处理
private
double
weight ;
//
累积的权值
private
ArrayList passedIDList ;
//
路径
public
PassedPath(
string
ID)
{
this
.curNodeID
=
ID ;
this
.weight
=
double
.MaxValue ;
this
.passedIDList
=
new
ArrayList() ;
this
.beProcessed
=
false
;
}
#region
property
public
bool
BeProcessed
{
get
{
return
this
.beProcessed ;
}
set
{
this
.beProcessed
=
value ;
}
}
public
string
CurNodeID
{
get
{
return
this
.curNodeID ;
}
}
public
double
Weight
{
get
{
return
this
.weight ;
}
set
{
this
.weight
=
value ;
}
}
public
ArrayList PassedIDList
{
get
{
return
this
.passedIDList ;
}
}
#endregion
}
另外,还需要一个表PlanCourse来记录规划的中间结果,即它管理了每一个节点的PassedPath。
///
<summary>
///
PlanCourse 缓存从源节点到其它任一节点的最小权值路径=》路径表
///
</summary>
public
class
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
)
{
throw
new
Exception(
"
The origin node is not exist !
"
) ;
}
this
.InitializeWeight(originNode) ;
}
private
void
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>
public
class
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
//
表示规划结束
return
this
.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
=
new
string
[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
}