【问题标题】:Visitor (pattern) to compute AbstractTree depth访问者(模式)计算 AbstractTree 深度
【发布时间】:2018-04-13 17:45:43
【问题描述】:

我在大学有这样一个任务来写一个访问者,它计算 AbstractTree 深度。这是树:

public abstract class AbstractTree {
    public abstract void Accept(AbstractVisitor abstractVisitor);
}

public class Leaf : AbstractTree {
    public override void Accept(AbstractVisitor visitor) {
        visitor.VisitLeaf(this);
    }
}

public class Node : AbstractTree {
    private AbstractTree Left { get; set; }
    private AbstractTree Right { get; set; }

    public Node(AbstractTree left, AbstractTree right) {
        Left = left;
        Right = right;
    }

    public override void Accept(AbstractVisitor visitor) {
        visitor.VisitNode(this);

        if (Left != null)
            Left.Accept(visitor);
        if (Right != null)
            Right.Accept(visitor);
    }
}

还有 AbstractVisitor:

public abstract class AbstractVisitor {
    public abstract void VisitLeaf(Leaf tree);

    public abstract void VisitNode(Node tree);
}

但是我该如何编写具体的 DepthVisitor 呢?当访问者知道树结构时,我知道如何执行此任务(depth-computing visitor that knows about the tree structure),但在这种情况下,访问者几乎不了解树结构(必须这样做,任务是这样制定的)。

【问题讨论】:

    标签: design-patterns visitor-pattern


    【解决方案1】:

    您可以绘制树的一些属性并将每个访问节点的深度存储在访问者中。

    • 一棵树只有一个根,所以访问的第一个节点的深度为 0
    • 每个节点的两个子节点的深度+1

    您的访问者可以保留(树、深度)对的地图。

    1. 如果当前节点未知,则它必须是根节点。存储 (root, 0) 和 (root.Left, 1), (root.Right, 1)。
    2. 对于任何其他节点 n,从 map 中获取节点的深度 d(它必须存在,因为已经访问过父节点)并存储 (n.Left, d+1), (n.Right, d +1)

    【讨论】:

    • 你的答案假设游客知道存在左右之类的东西,所以这是错误的。让我举个例子:如果我得出的结论是 Node 应该有 3 个孩子而不是 2 个呢?然后访问者将不再工作。它不应该依赖于树的实现。
    • @maxymilianz 只要知道一个节点有孩子,就可以在不知道左右的情况下制定它。我使用了LeftRight,因为问题中的代码无法获取节点的所有子节点。我认为假设树节点有子节点是公平的,您可以轻松更改方案以使用任意数量的子节点。
    猜你喜欢
    • 2011-09-12
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多