获取树中的下一个项目

发布于 2024-11-01 19:01:52 字数 746 浏览 1 评论 0原文

拥有一棵树(数据库中的逻辑树),其项目采用以下形式

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

等等(嵌套深度不限),我想从任意节点开始向下(或向上)获取下一个节点。

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

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

我的问题:

你会如何解决这个问题?

编辑1:

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

  • GetParentNode()
  • GetChildrenNodes()
  • GetNextSiblingNode()
  • 等所以

它类似于 Windows 窗体 TreeView

Having a tree (logical in DB) with items in the form

  1. List item A
  2. List item B
    1. List item C
      1. List item D
  3. List Item E
  4. List Item F
    1. List Item G

and so on (nesting depth not limited), I want to get the next node down (or up), starting from an arbitrary node.

Let's say, List Item D is given I want to write a function GetNextNode() that would return List Item E.

My idea would be to do some recursion stuff, but maybe there is a more clever way to handle this?

My question:

How would you solve this?

EDIT 1:

The tree can be accessed with functions like:

  • GetParentNode()
  • GetChildrenNodes()
  • GetNextSiblingNode()
  • etc.

So it's similar to e.g. e Windows Forms TreeView.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

汹涌人海 2024-11-08 19:01:52

我不得不这样做好几次。据记忆:

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;
                }
            }
        }
}

I've had to do this several times. From memory:

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;
                }
            }
        }
}
家住魔仙堡 2024-11-08 19:01:52

您可以通过递归或...最糟糕的 xD

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

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 "";
}

这并不适用于每种情况。您也应该搜索父节点的下一个节点。感谢文森特·范卡尔伯格的评论;-)

You can handle this via recursion or... worst xD

I think there are only 3 basic cases:

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 "";
}

This doesn't works for every scenario. You should search the parent's next node too. Thanks to Vincent Vancalbergh for the comment ;-)

世界如花海般美丽 2024-11-08 19:01:52
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;
    }
}
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;
    }
}
高速公鹿 2024-11-08 19:01:52

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

  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;实际上我需要用这种语言)

Since I got a great reply for the "down" part, I'll added my own "up" part. Maybe it is for some help of you; the up part is similar to:

  1. Get the previous sibling.
  2. If there is a previous sibling, get the deepest child node of this
    sibling.
  3. If there is no previous sibling, get the direct parent.

To get the deepest sibling (2.), I use the following code:

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

(Yes, I do know that this is VBScript; I needed it in fact in this language)

夜血缘 2024-11-08 19:01:52

也许试试这个:

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

Try this maybe:

TreeNode currentNode = treeView1.SelectedNode;
treeView1.selectedNode = currentNode.NextNode;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文