2012-04-24 83 views
5

不知道我是否被允许按照网站的规则做到这一点...但我会抓住我的机会...请忍受我,我只是一个学生.. 。:-)节点树<T>解释

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

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

公共无效添加(节点父,子节点){} - 增加了一个新的子节点的父节点

公共无效removeChild之(Nodeparent,子节点){} - 从父项中移除一个子节点。

公共节点getRootNode(){} - 返回树

公共无效setRoot(节点根){}的根 - 设置树的根节点

公共布尔包含(T数据){} - 检索树给定类型

公共无效DFS(子节点){} - 执行深度优先搜索的TRE e和输出每个节点(缩进)

公共无效BFS(节点子){} - 执行一个广度优先搜索树的并输出的每个节点(缩进)

  1. 树类应该被参数化以处理泛型类型T,允许创建字符串,文件等的树,例如Tree<String> tree = new Tree<String>()
  2. 树类应使用邻接表实现的树状结构和通过以下方式确定:Map<Node<T>, List<Node<T>>> tree = new HashMap<Node<T>, List<Node<T>>();

节点类也应进行参数化处理泛型类型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()]); 
     } 
    } 
} 
+8

“裸”与你?我保持着我的衣服 - 这是“忍受着我”。 – duffymo 2012-04-24 01:38:03

+0

:-)不错的一个...... – 2012-04-24 01:40:15

+0

一个有用的区别是:你在处理[this](http://en.wikipedia.org/wiki/Tree_%28data_structure%29)类树,或[this ](http://en.wikipedia.org/wiki/Tree_%28graph_theory%29)那种树?我猜想前者,但使用邻接列表的要求暗示了后者。 – Taymon 2012-04-24 01:47:43

回答

8

您使用地图以下的事情:

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

我可以说清楚树的工作原理吗?

+0

hmmmm 在我的Node类中我做了一个方法,它返回一个数组中的孩子....所以我应该那么,将节点作为节点的键和子节点作为数组... ...? – 2012-04-24 01:45:11

+1

想一想,哈希映射就是整棵树,你可以为自己保留对根节点的参照,然后它就像这样工作,有一个给定的节点,你可以调用哈希映射的get mehtod来获取子节点那么你可以迭代子节点并使用相同的映射来继续检索节点的子节点,当get方法返回null时,则有叶节点。 – 2012-04-24 01:48:55

+0

另一个细节,为了使它工作,你应该在您的Node类中实现equals和hashcode方法。 – 2012-04-24 01:49:38

0

看看列表中的2点,我会猜测1号点对您来说是最令人困惑的。

树本身可以参数化。树类的类型参数可以在用于创建节点的内部类中使用。也就是说,出于分配的目的,节点类可能应该在Tree类内部,以便它可以使用给予Tree类的T类型参数。

这样,树可以存储任何东西(字符串,文件,双打等)。 Node类简单地作为存储任何类型T对象的好方法。

+0

你是对的混淆部分... :-)在描述中,我们被要求为节点编写一个单独的类...我写了 – 2012-04-24 01:51:47

0

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

由于它看起来并不像你应该这样做,所以你可以让Tree<T>成为一个包装类,该类包含一个对象的引用(Node<T>)。您可以将所需方法的逻辑放在任何一个类中。

代码的起点可能是这个样子:

public class Tree<T> { 

    private Node<T> root; 

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

} 
+0

该描述明确指出,树类应该支持我写的方法我原来的帖子...但你能给我一个树类的初始化语句的例子...?请......只是试图让我的头在你说的话...这个其他绅士胡安也做了很多的感觉... – 2012-04-24 01:56:19

+0

添加了一个排序的例子。 – Taymon 2012-04-24 02:09:03

+0

这正是我如何开始写树类,但后来对整个地图问题感到困惑... – 2012-04-24 02:11:04