【问题标题】:Printing Tree and skipping certain values打印树并跳过某些值
【发布时间】:2020-05-01 02:39:20
【问题描述】:

这里我有以下代码和打印树结构的输入。我的问题是如何才能使具有“不可用”值的节点和叶子被跳过打印。

namespace Tree{public class TreeNode<T>

{
    private T value;

    private bool hasParent;

    private List<TreeNode<T>> children;


    public TreeNode(T value)
    {
        if (value == null)
        {
            throw new ArgumentNullException("Cannot insert null value");
        }

        this.value = value;
        this.children = new List<TreeNode<T>>();
    }
    public T Value
    {
        get
        {
            return this.value;
        }
        set
        {
            this.value = value;
        }
    }

    public int ChildrenCount
    {
        get
        {
            return this.children.Count;
        }
    }
    public void AddChild(TreeNode<T> child)
    {
        if (child == null)
        {
            throw new ArgumentNullException("Cannot insert null value");
        }
        if (child.hasParent)
        {
            throw new ArgumentException("The node already has a parent");
        }

        child.hasParent = true;
        this.children.Add(child);
    }
    public TreeNode<T> GetChild(int index)
    {
        return this.children[index];
    }
}

public class Tree<T>
{

    private TreeNode<T> root;
    public Tree(T value)
    {
        if (value == null)
        {
            throw new ArgumentNullException("Cannot insert null value");
        }

        this.root = new TreeNode<T>(value);
    }

    public Tree(T value, params Tree<T>[] children) : this(value)
    {
        foreach (Tree<T> child in children)
        {
            this.root.AddChild(child.root);
        }
    }

    public TreeNode<T> Root
    {
        get
        {
            return this.root;
        }
    }

    private void PrintDFS(TreeNode<T> root, string spaces)
    {
        if (this.root == null)
        {
            return;
        }
        Console.WriteLine(spaces + root.Value);

        TreeNode<T> child = null;
        for (int i = 0; i < root.ChildrenCount; i++)
        {
            child = root.GetChild(i);
            PrintDFS(child, spaces + "   ");
        }
    }
    public void TraverseDFS()
    {
        this.PrintDFS(this.root, string.Empty);
    }
}

public static class TreeExample
{
    static void Main()
    {

        Tree<string> tree =
        new Tree<string>("John",
            new Tree<string>("Jasmine",
                new Tree<string>("Jay"),
                new Tree<string>("Unavailable")),
             new Tree<string>("Unavailable",
                new Tree<string>("Jack"),
                new Tree<string>("Jeremy")),
            new Tree<string>("Johanna")

            );
    tree.TraverseDFS();


    }
}}

现在它打印 :(John, (Jasmine, (Jay), (Unavailable)), (Unavailable, (Jack, (Jeremy))), (Johanna))

我需要它来打印 :(John, (Jasmine, (Jay)), (Johanna))

所以基本上跳过每个值为“Unavailable”的叶子和每个值为“Unavailable”的节点以及该节点的所有子节点

谢谢!

【问题讨论】:

    标签: c# recursion printing tree


    【解决方案1】:

    这应该可行:

    private void PrintDFS(TreeNode<T> root, string spaces)
    {
        if (this.root == null
            || "Unavailable" == root.Value.ToString())
        {
            return;
        }
        ...
    

    【讨论】:

    • 当我输入您的解决方案时,它说“运算符'=='不能应用于'T'类型的操作数和字符串:
    【解决方案2】:

    接受的答案是对问题的字面正确答案,但它在逻辑上将关于如何处理树的逻辑融入到树本身中。树是一种集合或数据结构,您通常不会看到能够打印自身的列表或字典。相反,该集合提供了正确的方法来获取或更改其内容,以便您可以随心所欲。

    在您的情况下,您可以执行以下操作:

    public enum TreeVisitorResult {
        SkipNode,
        Continue
    }
    
    // the following two methods inside Tree<T>:
    
    public void VisitNodes(Func<TreeNode<T>, int, TreeVisitorResult> visitor) {
        VisitNodes(0, this.root, visitor);
    }
    
    private void VisitNodes(int depth, TreeNode<T> node,
        Func<TreeNode<T>, int, TreeVisitorResult> visitor) {
    
        if (node == null) {
            return;
        }
    
        var shouldSkip = visitor(node, depth);
        if (shouldSkip == TreeVisitorResult.SkipNode) {
            return;
        }
    
        TreeNode<T> child = null;
        for (int i = 0; i < node.ChildrenCount; i++) {
            child = node.GetChild(i);
            VisitNodes(depth + 1, child, visitor);
        }
    }
    

    如果你有这个方法,你可以在 Tree 类之外编写 Print 方法,如下:

    tree.VisitNodes((treeNode, depth) => { // <- this lambda will be called for every node
        if (treeNode.Value == "Unavailable") { // <- no need to ToString or cast here, since
                                               // we know that T is string here
            return TreeVisitorResult.SkipNode;
        } else {
            var spaces = new string(' ', depth * 3);
            Console.WriteLine(spaces + treeNode.Value);     
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2012-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      • 1970-01-01
      相关资源
      最近更新 更多