【问题标题】:Tree of Node<T> explainationNode<T> 解释树
【发布时间】:2012-04-24 01:36:05
【问题描述】:

不知道我是否可以根据网站的规则这样做......但我会抓住机会......请多多包涵,我只是一个学生...... :-)

我有一个大学作业...我很难理解课程应该做什么...我已经在三个不同的场合去找过我的老师,但我从他那里得到的答案根本没有帮助。无论如何,分配细节如下......

创建一个名为Tree 的类,它充当节点的容器。树类应该支持以下方法。

public void add(Node parent, Node child){} -- 向父节点添加一个新的子节点

public void removeChild(Nodeparent, Node child){} -- 从父节点移除子节点。

public Node getRootNode(){} -- 返回树的根

public void setRoot(Node root){} -- 设置树的根节点

public boolean contains(T data){} -- 在树中搜索给定类型

public void dfs(Node child){} -- 执行树的深度优先搜索并输出每个节点(缩进)

public void bfs(Node child){} -- 执行树的广度优先搜索并输出每个节点(缩进)

  1. 应该对树类进行参数化以处理通用类型 T,从而允许创建字符串树、文件树等... Tree&lt;String&gt; tree = new Tree&lt;String&gt;()
  2. 树类应使用邻接表实现树结构,并按以下方式定义:Map&lt;Node&lt;T&gt;, List&lt;Node&lt;T&gt;&gt;&gt; tree = new HashMap&lt;Node&lt;T&gt;, List&lt;Node&lt;T&gt;&gt;();

节点类也应该被参数化以处理泛型类型 T 并公开几个方法...

现在我已经编写了运行良好的 Node 类......老实说,我确信我已经编写了一个正在创建树的 Node 类。但是在阅读了 Tree 类描述后,我很困惑。我应该存储在树图中的内容。我很难想象整个事情。

也许有人可以解释老师想要什么并让我朝着正确的方向前进。我在寻找代码本身...只是想了解我应该做什么。

我的节点类

public class Node<T> 
{
    private Node<T> root; // a T type variable to store the root of the list
    private Node<T> parent; // a T type variable to store the parent of the list
    private T child;
    private List<Node<T>> children = new ArrayList<Node<T>>(); // a T type list to store the children of the list

    // default constructor
    public Node(T child)
    {
        setParent(null);
        setRoot(null);
        setItem(child);
    }

    // constructor overloading to set the parent
    public Node(Node<T> parent)
    {
        this.setParent(parent);
        //this.addChild(parent);
    }

    // constructor overloading to set the parent of the list  
    public Node(Node<T> parent, Node<T> child)
    {
        this(parent);
        this.children.add(child);
    }

    /**
    * This method doesn't return anything and takes a parameter of 
    * the object type you are trying to store in the node 
    * 
    * @param  Obj  an object
    * @param 
    **/
    public void addChild(Node<T> child)
    {
        child.root = null;
        child.setParent((Node<T>)this);
        this.children.add(child); // add this child to the list
    }

    public void removeChild(Node<T> child)
    {
        this.children.remove(child); // remove this child from the list
    }

    public Node<T> getRoot() {
        return root;
    }

    public boolean isRoot()
    {
        // check to see if the root is null if yes then return true else return false
        return this.root != null;     
    }

    public void setRoot(Node<T> root) {
        this.root = root;
    }

    public Node<T> getParent() {
        return parent;
    }

    public void setParent(Node<T> parent) {
        this.parent = parent;
    }

    public T getItem() {
        return child;
    }

    public void setItem(T child) {
        this.child = child;
    }

    public boolean hasChildren()
    {
        return this.children.size()>0;
    }

    @SuppressWarnings("unchecked")
    public Node<T>[] children()
    {
        return (Node<T>[]) children.toArray(new Node[children.size()]);
    }

    @SuppressWarnings({ "unchecked"})
    public Node<T>[] getSiblings()
    {
        if(this.isRoot()!=false && parent==null)
        {
            System.out.println("this is root or there are no siblings");
            return null;
        }
        else{
            List<Node<T>> siblings = new ArrayList<Node<T>>((Collection<? extends Node<T>>) Arrays.asList(new Node[this.parent.children.size()]));  
            Collections.copy(siblings, this.parent.children);  
            siblings.remove(this);
            return siblings.toArray(new Node[siblings.size()]);
        }
    }
}

【问题讨论】:

  • “裸”与你?我一直在穿衣服——这是“忍受我”。
  • 一个有用的区别:您是在处理this 类型的树,还是this 类型的树?我猜是前者,但使用邻接列表的要求表明后者。
  • 我认为您提供的第一个链接看起来非常接近我们所讲授的内容......

标签: java tree


【解决方案1】:

您将地图用于以下事情:

hashmap 的键是给定节点,hashmap 的值是给定节点的子节点。

public class Tree<T> {
    private Node<T> rootNode;
    private HashMap<Node<T>, List<Node<T>> tree;

    //and then some kind of function to go through the tree.
    public void expandNode(Node<T> node) {
        if (tree.get(node) == null) {
            System.out.println(node);
            return;
        }
        for(Node<T> n : tree.get(node)) {
            System.out.println(node);
            expandNode(n);
        }
    }
}

我能说清楚这棵树是如何工作的吗??

【讨论】:

  • hmmmm 在我的 Node 类中,我创建了一个方法,该方法返回数组中的子节点....所以我应该做的是,将 node 作为键,将节点的子节点作为数组...?
  • 这样想,hash map就是整棵树,你可以为自己保留一个对根节点的引用,然后它就这样工作,有一个给定的节点,你调用get方法哈希映射来获取该节点的子节点,因此您可以遍历子节点并使用相同的映射继续检索节点的子节点,当 get 方法返回 null 时,您就有了叶节点。
  • 另外一个细节,为了让它工作,你应该在你的 Node 类中实现 equals 和 hashcode 方法。
  • hmmm...好吧,我想我会按照您给我的想法工作...并将在我的节点类中实现哈希码和equals方法...但按照我的说法'不知道我将在节点中存储什么类型的对象......我可以在什么基础上生成我的哈希码?和equals方法?#
  • 您可以在托管对象上调用 hashCode,因为这是从 Object 类继承的方法
【解决方案2】:

查看列表中的 2 点,我猜第 1 点最让您感到困惑。

树本身可以参数化。树类的类型参数可以在用于创建节点的内部类中使用。也就是说,为了你的赋值,节点类可能应该在 Tree 类中,这样它就可以使用给 Tree 类的 T 类型参数。

这样,树可以存储任何东西(字符串、文件、双精度等)。 Node 类只是作为存储任何类型 T 对象的好方法。

【讨论】:

  • 你对混淆部分是正确的...... :-) 在描述中,我们被要求为节点编写一个单独的类......我已经写过
【解决方案3】:

这有点奇怪。如果我这样做并且作业没有另外说明,我可能根本不会编写 Tree 类;我只是将 Node 用作递归数据结构,并让树的根节点代表整棵树。

由于看起来您不应该这样做,您可以将Tree&lt;T&gt; 设为一个包装类,该类引用单个Node&lt;T&gt; 对象。您可以将所需方法的逻辑放在任一类中。

代码的开头可能如下所示:

public class Tree<T> {

    private Node<T> root;

    public Tree(Node<T> root) {
        this.root = root;
    }

}

【讨论】:

  • 描述清楚地表明 Tree 类应该支持我在原始帖子中编写的方法......但是你能给我一个 Tree 类的初始化语句的例子......吗?拜托……只是想让我理解你所说的话……另一位胡安先生也很有意义……
  • 这正是我开始编写 Tree 类的方式,但后来对整个 Map 问题感到困惑......
  • 唉,没关系,我一直在想这一切都错了。我假设边缘应该是节点状态的一部分。他们不是。
猜你喜欢
  • 2016-04-20
  • 2018-06-14
  • 2015-02-27
  • 2011-09-24
  • 2014-08-03
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多