【问题标题】:Get next item in a tree获取树中的下一个项目
【发布时间】:2011-08-05 09:17:55
【问题描述】:

拥有一棵树(在 DB 中是逻辑的),其中包含表单中的项目

  1. 列表项 A
  2. 列表项 B
    1. 列表项 C
      1. 列表项 D
  3. 列表项 E
  4. 列表项 F
    1. 列表项 G

以此类推(嵌套深度不限),我想从任意节点开始向下(或向上)下一个节点。

假设给定List Item D,我想编写一个函数GetNextNode(),它会返回List Item E

我的想法是做一些递归的东西,但也许有更聪明的方法来处理这个?

我的问题:

你会怎么解决这个问题?

编辑 1:

可以使用以下函数访问树:

  • GetParentNode()
  • GetChildrenNodes()
  • GetNextSiblingNode()

所以它类似于例如e Windows 窗体TreeView

【问题讨论】:

  • 您是在问如何将其存储在数据库中,您的项目是否已经在表单的 TreeView 中,或者如何创建类似的东西?
  • 你能多说一下树的结构是如何表示的吗?
  • 有许多 许多 不同的迭代树的方法 - 所谓的“树遍历”是一个复杂的主题。 > en.wikipedia.org/wiki/Tree_traversal
  • @MattDavey 我知道这有点晚了:) 但是大多数树操作都可以在没有递归的情况下完成。这对于堆栈空间有限和/或每个子例程成本高的系统来说是必需的。尽管如果递归在子例程的尾部,一个体面的编译器通常可以将其优化掉。当然,使用递归的版本通常更容易阅读。

标签: c# recursion tree


【解决方案1】:

我不得不多次这样做。凭记忆:

public Node GetBelowNode()
{
    if (GetChildrenNodes().count > 0)
        return GetChildrenNodes()[0];
    else
        if (GetNextSiblingNode() != null)
            return GetNextSiblingNode();
        else
        {
            Node curr = this;
            Node parent; 
            while (true)
            {
                parent = curr.GetParentNode();
                if (parent == null)
                    return null;
                else
                {
                    if (parent.GetNextSiblingNode() != null)
                        return parent.GetNextSiblingNode();
                    else
                        curr = parent;
                }
            }
        }
}

【讨论】:

    【解决方案2】:

    您可以通过递归或...最糟糕的 xD 来处理这个问题

    我认为只有三种基本情况:

    private string getNext(TreeNode node)
    {
        if (node.FirstNode != null)
        {
            return node.FirstNode.Name;
        }
        else
        {
            if (node.NextNode != null)
            {
                return node.NextNode.Name;
            }
            else if (node.Parent.NextNode != null)
            {
                return node.Parent.NextNode.Name;
            }
        }
    
        return "";
    }
    

    这并不适用于所有场景。您也应该搜索父节点的下一个节点。感谢 Vincent Vancalbergh 的评论;-)

    【讨论】:

    • 嵌套深度应该是任意的。
    • FirstNode 是第一个子节点,NextNode 是当前节点之后的第一个“兄弟”,Parent 是父节点;-)
    • 如果父母没有兄弟姐妹但祖父有兄弟姐妹怎么办。还是曾祖父。有人的投票需要撤回..
    【解决方案3】:
    public Party Next {
        get {
            if (this.children.Count > 0) return this.children[0];
    
            Party target = this;
            do {
                if (target.NextSibling != null) return target.NextSibling;
            } while ((target = target.Parent) != null);
    
            return null;
        }
    }
    
    public Party Previous {
        get {
            if (Parent != null && Parent.children.Count > 0 && this == Parent.children[0]) {
                return Parent;
            }
    
            Party target = this;
    
            do {
                if (target.PreviousSibling != null) { target = target.PreviousSibling; break; }
            } while ((target = target.Parent) != null);
    
            if (target != null) {
                while (target.children.Count > 0) {
                    target = target.children[target.children.Count - 1];
                }
            }
    
            return target;
        }
    }
    

    【讨论】:

      【解决方案4】:

      由于“向下”部分得到了很好的答复,我将添加自己的“向上”部分。也许是为了你的一些帮助;上部分类似于:

      1. 获取上一个兄弟。
      2. 如果有前一个兄弟节点,则获取此兄弟节点的最深子节点 兄弟姐妹。
      3. 如果没有上一个兄弟姐妹,则获取直接父级。

      为了获得最深的兄弟 (2.),我使用以下代码:

      function getDeepestChild( page )
          dim result
          set result = nothing
      
          dim childPages
          set childPages = page.ChildPages
      
          if childPages.Count>0 then
              dim p
              set p = childPages(childPages.Count-1)
              ' recurse.
              set result = getDeepestChild( p )
          else
              set result = page
          end if
      
          set getDeepestChild = result
      end function
      

      (是的,我知道这是 VBScript;实际上我需要这种语言)

      【讨论】:

        【解决方案5】:

        不妨试试这个:

        TreeNode currentNode = treeView1.SelectedNode;
        treeView1.selectedNode = currentNode.NextNode;
        

        【讨论】:

        • 这是一个TreeView 树(我只有一个逻辑内存树)。此外,您的功能似乎可以工作for siblings only
        猜你喜欢
        • 1970-01-01
        • 2021-04-26
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-21
        • 1970-01-01
        相关资源
        最近更新 更多