1.1.1. 简介
递归是指某个函数或过程直接或间接的调用自身。一般地一个递归包括递归出口和递归体两部分,递归出口确定递归到何时结束,而递归体确定递归求解时的递推关系。递归算法有两个基本特征:一是递归算法是一种分而治之的、把复杂问题分解为简单问题的求解问题方法,对于求解某些复杂问题,递归算法分析问题的方法是有效地;而是递归算法的时间、控件效率通常比较差。因此对解决某些问题时,我们希望用递归算法分析问题,用非递归算法解决问题,这就需要把递归算法转换为非递归算法。
把递归算法转化为非递归算法有如下三种基本方法:
(1). 通过分析,跳过分解过程,直接用循环结构的算法实现求解过程。
(2). 自己用栈模拟系统的运行时栈,通过分析只保存必须保存的信息,从而用非递归算法替代递归算法。
(3). 利用栈保存参数,由于栈的后进先出特性吻合递归算法的执行过程,因而可以用非递归算法替代递归算法。
1.1.2. 应用场景
在系统中,构造树形结构(WBS模板树、具体项目的WBS树、项目群树、省市县树形结构等)时用到了递归算法。就结构简单的树形结构而言,对性能的影响并不明显,例如项目群树,它的属于一维的树形结构,且采用递归算法的递归深度小于3。但是,对于复杂的树形结构,采用递归算法实现时,响应速度普遍较慢,如WBS模板树、具体项目的WBS树以及省市县树形结构等,都是多维的,且递归深度不确定(至少大于3)。因此,在构造复杂的树性结构时需要把递归算法转换为非递归算法。除此之外,在其它复杂的递归算法中,也可以采用将递归算法转换为非递归算法的方法,以提高算法的性能。
1.1.3. 应用示例及效果
在系统中,将递归算法转换为非递归算法大大提高系统的性能,以省市县树形结构的加载为例进行说明,关键程序代码如下:
// 定义树形结构数据集合
ObservableCollection<E_Region> proviceList = new ObservableCollection<E_Region>();
E_Region regionTemp = new E_Region(); //
for (int i = 0; i < dt.Rows.Count; i++)
{
regionTemp = new E_Region();
regionTemp.RegionID = dt.Rows[i]["RegionID"].ToString();
regionTemp.RegionFather = dt.Rows[i]["RegionFather"].ToString();
regionTemp.RegionName = dt.Rows[i]["RegionName"].ToString();
regionTemp.RegionDescription = dt.Rows[i]["RegionDescription"].ToString();
FindRegion(regionTemp, region, proviceList); //
region = regionTemp;
}
/// <summary>
/// 递归加载数据
/// </summary>
/// <param name="temp">当前对象</param>
/// <param name="parent">父级对象</param>
/// <param name=" proviceList ">树形数据集合</param>
private void FindRegion(E_Region temp, E_Region parent, ObservableCollection<E_Region> proviceList )
{
if (temp.RegionFather == "0")
{
temp.ParentRegion = null;
proviceList.Add(temp);
}
else if (temp.RegionFather != parent.RegionFather)
{
if (temp.RegionFather == parent.RegionID)
{
parent.RegionItemView1.Add(temp);
temp.ParentRegion = parent;
}
else
{
FindRegion(temp, parent.ParentRegion);
}
}
else if (parent.RegionFather == parent.RegionFather)
{
temp.ParentRegion = parent.ParentRegion;
parent.ParentRegion.RegionItemView1.Add(temp);
}
}
采用非递归算法构造省市县树形结构,提高了效率,从以往的20秒多提高到现在的5秒。