我想实现在一个树下工具节点名称找到节点的编号,属于skyline的二次开发,但整个过程应该主要是递归逻辑不清的问题,代码如下,我在100标记行判断是否找到目标,如果知道,则退出所以递归,将找到的对象的对应的ID返回,可是怎么调试都跳不出来,return之后还在循环体内,不知道逻辑哪里有错误,我将return改为break,试图用break终止循环,可似乎只终止本次调用的函数,完了之后还在循环体内。问题在哪呢,我是初学者,麻烦哪位大虾多指点一下,非常感谢!!!
/// <summary>
/// 根据父节点号及子节点名称返回子节点ID
/// </summary>
/// <param name="iParentID">父节点ID</param>
/// <param name="sObjectNM">子节点名称</param>
/// <returns>子节点ID</returns>
private static int _TraverseBranch(int iParentID, string sObjectNM)
{
try
{
//Get the first child item of this group.
int iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.CHILD);
if (iChildID == 0)
return 0; //Start with the first child item and traverse
//all of the sibling items in that group. while (iChildID != 0)
{
if (InformationTree5.IsGroup(iChildID) > 0)
{
//If we are here, this tree item is a group.
//A recursive call - traverse all of the tree items under this group.
_TraverseBranch(iChildID, sObjectNM);
}
else
{
//If we are here, this tree item is an object. //Get an interface to the object that this is its ID.
TerraExplorerX.ITerrainColoredObject5 pITEObject =
InformationTree5.GetObjectEx(iChildID, "") as TerraExplorerX.ITerrainColoredObject5;
string tmp = getItemName(iChildID); 100: if ((tmp.Remove(tmp.Length - 1, 1)).Trim() == sObjectNM.Trim())
return iChildID;
}
iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.NEXT);
}
return iChildID;
}
catch (Exception ex)
{ return 0; }
}
/// <summary>
/// 根据父节点号及子节点名称返回子节点ID
/// </summary>
/// <param name="iParentID">父节点ID</param>
/// <param name="sObjectNM">子节点名称</param>
/// <returns>子节点ID</returns>
private static int _TraverseBranch(int iParentID, string sObjectNM)
{
try
{
//Get the first child item of this group.
int iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.CHILD);
if (iChildID == 0)
return 0; //Start with the first child item and traverse
//all of the sibling items in that group. while (iChildID != 0)
{
if (InformationTree5.IsGroup(iChildID) > 0)
{
//If we are here, this tree item is a group.
//A recursive call - traverse all of the tree items under this group.
_TraverseBranch(iChildID, sObjectNM);
}
else
{
//If we are here, this tree item is an object. //Get an interface to the object that this is its ID.
TerraExplorerX.ITerrainColoredObject5 pITEObject =
InformationTree5.GetObjectEx(iChildID, "") as TerraExplorerX.ITerrainColoredObject5;
string tmp = getItemName(iChildID); 100: if ((tmp.Remove(tmp.Length - 1, 1)).Trim() == sObjectNM.Trim())
return iChildID;
}
iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.NEXT);
}
return iChildID;
}
catch (Exception ex)
{ return 0; }
}
/// 根据父节点号及子节点名称返回子节点ID
/// </summary>
/// <param name="iParentID">父节点ID</param>
/// <param name="sObjectNM">子节点名称</param>
/// <returns>子节点ID</returns>
private static int _TraverseBranch(int iParentID, string sObjectNM)
{
try
{
//Get the first child item of this group.
int iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.CHILD);
if (iChildID == 0)
return 0; //Start with the first child item and traverse
//all of the sibling items in that group. if (iChildID != 0)
{
if (InformationTree5.IsGroup(iChildID) > 0)
{
//If we are here, this tree item is a group.
//A recursive call - traverse all of the tree items under this group.
return _TraverseBranch(iChildID, sObjectNM);
}
else
{
//If we are here, this tree item is an object. //Get an interface to the object that this is its ID.
TerraExplorerX.ITerrainColoredObject5 pITEObject =
InformationTree5.GetObjectEx(iChildID, "") as TerraExplorerX.ITerrainColoredObject5;
string tmp = getItemName(iChildID); if ((tmp.Remove(tmp.Length - 1, 1)).Trim() == sObjectNM.Trim())
return iChildID;
}
}
}
catch (Exception ex)
{ return 0; }
}
递归相当于一个循环,你这里又使用了while,肯定有问题,上面的代码我没测试,我觉得思路没什么问题,你试试看
iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.NEXT);
return _TraverseBranch(iChildID, sObjectNM);
就是把这段if ((tmp.Remove(tmp.Length - 1, 1)).Trim() == sObjectNM.Trim())
return iChildID;
改成if ((tmp.Remove(tmp.Length - 1, 1)).Trim() == sObjectNM.Trim())
{
return iChildID;
}else
{
iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.NEXT);
return _TraverseBranch(iChildID, sObjectNM);}
如此改了之后还是不行,为什么要用while呢,主要是只知道节点名称,需要不断的循环来查找到对象,如下图所示的节点图
return 0; 写在后面 如: else {return 0;} //while (iChildID != 0) 换成 if iChildID != 0 调试一下看看
//A recursive call - traverse all of the tree items under this group.
int iFoundID = _TraverseBranch(iChildID, sObjectNM);
if (iFoundID != 0) return iFoundID;
private static int iObjectID
{ get; set; } /// <summary>
/// 根据父节点号及子节点名称返回子节点ID
/// </summary>
/// <param name="iParentID">父节点ID</param>
/// <param name="sObjectNM">子节点名称</param>
/// <returns>子节点ID</returns>
private static int _TraverseBranch(int iParentID, string sObjectNM)
{
try
{
//Get the first child item of this group.
int iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.CHILD);
if (iChildID == 0)
return 0; //Start with the first child item and traverse
//all of the sibling items in that group. while (iChildID != 0)
{
if (InformationTree5.IsGroup(iChildID) > 0)
{
//If we are here, this tree item is a group.
//A recursive call - traverse all of the tree items under this group.
_TraverseBranch(iChildID, sObjectNM);
}
else
{
//If we are here, this tree item is an object. //Get an interface to the object that this is its ID.
TerraExplorerX.ITerrainColoredObject5 pITEObject =
InformationTree5.GetObjectEx(iChildID, "") as TerraExplorerX.ITerrainColoredObject5;
string tmp = getItemName(iChildID); if ((tmp.Remove(tmp.Length - 1, 1)).Trim() == sObjectNM.Trim())
{
iObjectID= iChildID;
break;
}
}
iChildID = InformationTree5.GetNextItem(iChildID, ItemCode.NEXT);
}
return iChildID;
}
catch (Exception ex)
{ return 0; }
}
这个差不多了,lz试试看/// <summary>
/// 根据父节点号及子节点名称返回子节点ID
/// </summary>
/// <param name="iParentID">父节点ID</param>
/// <param name="sObjectNM">子节点名称</param>
/// <returns>子节点ID</returns>
private static bool _TraverseBranch(int iParentID, string sObjectNM, ref int resultID)
{
try
{
if (InformationTree5.IsGroup(iParentID) > 0)
{
int iChildID = InformationTree5.GetNextItem(iParentID, ItemCode.CHILD); while (iChildID != 0)
{
bool isFound=_TraverseBranch(iChildID, sObjectNM,ref resultID);
if (isFound)
{
return true;
}
else
{
iChildID = InformationTree5.GetNextItem(iChildID, ItemCode.NEXT);
}
}
}
else
{
TerraExplorerX.ITerrainColoredObject5 pITEObject =
InformationTree5.GetObjectEx(iParentID, "") as TerraExplorerX.ITerrainColoredObject5;
string tmp = getItemName(iParentID); if ((tmp.Remove(tmp.Length - 1, 1)).Trim() == sObjectNM.Trim())
{
resultID = iParentID;
return true;
}
}
return false;
}
catch (Exception ex)
{ return false; }
}
好,分全给你了,再次谢谢啊!
首先第一个参数,iParentID,你的注释是父节点ID,这里我觉得没有必要是父节点,就是树中任意的一个节点,因为递归下去以后肯定要到叶子节点。
然后第一个If就是判断该节点是否是叶子节点,如果是进行比较,匹配返回true,不匹配返回false,这个是递归结束条件,比较简单。
如果不是叶子节点,那么对该节点的所有子节点进行递归,这里注意几个方面。因为要在所有子节点查找,所以要有while循环,同时如果已经找到不希望继续查找。
对第一个子节点进行递归,找到返回true,这里就是你提到的为什么会几次执行return true,就是你递归几层就返回几层,一直到最上层,函数调用才结束。
没有找到对下一个子节点进行递归,直到所有子节点结束,没有找到返回false,一直返回到最上层。递归本质也是函数调用,你可以自己把具体执行的堆栈画出来,这样对理解递归很有帮助。