概述:
最近发现,递归算法在实际项目开发中的应用非常广泛,就最近的一个项目中四次用到了递归算法,因此举出项目开发中的一个例子作为讲解。
递归算法的思想:
递归算法是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。
递归算法的特点:
递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1)递归就是在过程或函数里调用自身。
(2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3)递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归 算法设计程序。
(4)在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多 容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
问题:
在实际项目中,我们往往需要动态生成树形结构的菜单来实现数据的管理,如图1所示;或者是需要动态生成树形的图表结构,如图2所示。这些树形结构往往没有层级限制。
图1 树形菜单结构
图2 树形图表结构
在此,以图2为例提出问题及解决方案。
数据库设计:
列名 | 类型 | 是否为空 | 备注 |
Id | bigint | 否 | 编号,主键 |
ItemName | varchar(50) | 否 | 子项名称 |
StartTime | datetime | 否 | 开始时间 |
EndTime | datetime | 否 | 结束时间 |
FartherCode | varchar(50) | 否 | 父节点编码,如果值为’0’代表该节点为一级节点 |
Code | varchar(50) | 否 | 当前节点编码 |
实现:
(1)读取所有的一级节点,放入DataTable中;
(2)遍历DataTable的每一行(即DataRow);
(3)对于给定的DataRow,如果该节点没有根节点,返回对应的字符串,否则,获取该节点的的所有子节点得到DataTable,跳转到第(2)步,最终将所有得到的字符串叠加返回;
核心算法:
DataTable dtPlan = ProPlanDao.SelectBySql(base.Conn, "select * from ProPlan where FartherCode='0'"); //获取所有根节点
string html = string.Empty;
if (dtPlan.Rows.Count > 0){
html += "[";
//遍历所有子节点
for (int i = 0; i < dtPlan.Rows.Count; i++){
html += GetJson(dtPlan.Rows[i]) + ",";}
html = html.Substring(0, html.Length - 1) + "]";
}
//递归函数
public string GetJson(DataRow dr){
//是否拥有子节点
bool hasSon = ProPlanDao.HasSub(base.Conn, Code);
//递归出口
if (!hasSon){
string result = "{\"id\":" + Id + ",";
result += "\"rownum\":\"" + (rowNumber++) + "\",";
result += "\"name\":\"" + ItemName + "\",";
result += "\"start\":\"" + StartTime + "\",";
result += "\"end\":\"" + EndTime + "\",";
result += "\"time\":\"" + (EndTime - StartTime) + "\",";
result += "\"option\":\"<a href='#'>添加子任务</a> <a href='#'>编辑</a> <a href='#'>删除</a>\"}";
return result;
}
else{
DataTable dtSon = ProPlanDao.SelectSub(base.Conn, Code);
string result = "{\"id\":" + Id + ",";
result += "\"rownum\":\"" + (rowNumber++) + "\",";
result += "\"name\":\"" + ItemName + "\",";
result += "\"start\":\"" + StartTime + "\",";
result += "\"end\":\"" + EndTime + "\",";
result += "\"time\":\"" + (EndTime - StartTime) + "\",";
result += "\"option\":\"<a href='#'>添加子任务</a> <a href='#'>编辑</a> <a href='#'>删除</a>\",";
result += "\"state\":\"closed\",";
result += "\"children\":[";
//遍历该节点的所有子节点
for (int i = 0; i < dtSon.Rows.Count; i++){
result += GetJson(dtSon.Rows[i]) + ",";}
result = result.Substring(0, result.Length - 1) + "]}";
return result;
}
}
开发环境:
Windows XP 、Visual Studio 2010
开发语言:
C#、html、asp.net、javascript、EasyUi、jQuery