递归改非递归
递归用的场合很多,比如求一棵树的深度,树查找节点等,递归的好处就是代码简洁,代码易读,缺点是效率不高,深度限制。随着树的深度增加,程序对函数栈空间的使用越来越多,由于栈空间有限( 栈大小受编译器限制,例如VC,VS2003默认1M),递归方法可能导致内存耗尽问题。
解决方法有两个:
- 使用非递归算法,例如实现前序、中序、后序遍历,即仿照递归算法执行时的函数工作栈的变化状况,建立一个栈对当前路径上的节点进行记录( 可以用Queue,Stack,HashTable或其它都可以 ),然后根据栈顶元素是否存在左右节点的不同情况决定下一步操作;
- 使用线索二叉树,即根据遍历规则,在每个叶子上增加指向后续节点的指针。
递归算法改成非递归算法也很多方法,这里给出两个例子:
1. 循环设定所有控件和子控件的Text属性:
递归:
private void SetTextAll()
{ /* 调用 */foreach (System.Web.UI.Control ctl in this.Controls)
{ SetControlText(ctl); /* 递归 */}
SetControlText_New(this.Controls);/* 非递归 */
}
/// <summary>/// 递归方法设置UI控件的Text/// </summary>public void SetControlText(System.Web.UI.Control control)
{if (control == null) return;
control.Text = "abc"; if (control.Controls.Count > 0) {foreach (System.Web.UI.Control ctl in control.Controls)
{SetControlText(ctl);
}
}
}
非递归:
/// <summary>/// 非递归方法设置UI控件的Text/// </summary>public void SetControlText_New(System.Web.UI.Control.ControlCollection c)
{if (c == null) return;
System.Collections.Queue<Control> q = new System.Collections.Queue<Control>();foreach (Control control in c)
{Control temp = control;
bool IsHasChildFolder = true;
q.Clear();
while (IsHasChildFolder) {foreach (Control ctl in temp.Controls)
{ ctl.Text = "abc"; if (ctl.Controls.Count > 0) {q.Enqueue(ctl);
}
}
if (q.Count > 0) {temp = q.Dequeue();
}
else { IsHasChildFolder = false;}
}
}
}
2. 在TreeView中查找某个节点:
递归:
private TreeNode FindNode( TreeNode tnParent, string strValue )
{if( tnParent == null ) return null;
if( tnParent.Text == strValue ) return tnParent;
TreeNode tnRet = null;foreach( TreeNode tn in tnParent.Nodes )
{tnRet = FindNodeExt( tn, strValue );
if( tnRet != null ) break;
}
return tnRet;}
非递归:
private TreeNode FindNode( TreeNode tnParent, string strValue )
{if( tnParent == null ) return null;
if( tnParent.Text == strValue ) return tnParent;
else if( tnParent.Nodes.Count == 0 ) return null;
TreeNode tnCurrent, tnCurrentPar;
//Init nodetnCurrentPar = tnParent;
tnCurrent = tnCurrentPar.FirstNode;
while( tnCurrent != null && tnCurrent != tnParent )
{while( tnCurrent != null )
{if( tnCurrent.Text == strValue ) return tnCurrent;
else if( tnCurrent.Nodes.Count > 0 )
{ //Go into the deepest node in current sub-pathtnCurrentPar = tnCurrent;
tnCurrent = tnCurrent.FirstNode;
}
else if( tnCurrent != tnCurrentPar.LastNode )
{ //Goto next sible nodetnCurrent = tnCurrent.NextNode;
}
else break;}
//Go back to parent node till its has next sible node while( tnCurrent != tnParent && tnCurrent == tnCurrentPar.LastNode ) {tnCurrent = tnCurrentPar;
tnCurrentPar = tnCurrentPar.Parent;
}
//Goto next sible node if( tnCurrent != tnParent )tnCurrent = tnCurrent.NextNode;
}
return null;
}
调用:
/*程序调用*/TreeNode tnRet = null;foreach( TreeNode tn in yourTreeView.Nodes )
{tnRet = FindNodeExt( tn, yourValue );
if( tnRet != null ) break;
}
浙公网安备 33010602011771号