2014-06-22 2 views
-2

주어진 노드의 하위 목록을 보유하는 트리를 구현하려고합니다. 내 주요 메서드에서 출력 크기를 시도 할 때 1을 반환합니다. 내 createNode 메서드가 잘못 되었더라도 누구나 볼 수 있습니까? 그리고 누군가 화나기 전에, 나는 당신이 내가하려고하는 것을 볼 수 있도록 모든 코드를 포함하고 있습니다. :)내 Java 구현 트리에 무엇이 잘못 되었습니까?

public class LinkedTree<E> implements Tree<E> { 

    protected TreePosition<E> root; // reference to the root 
    protected int size; // number of nodes 

    public LinkedTree() { 
     root = null; // start with an empty tree 
     size = 0; 
    } 

    /** Returns the number of nodes in the tree. */ 
    public int size() { 
     return size; 
    } 

    /** Returns whether the tree is empty. */ 
    public boolean isEmpty() { 
     return (size == 0); 
    } 

    /** Returns whether a node is internal. */ 
    public boolean isInternal(Position<E> v) throws InvalidPositionException { 
     return !isExternal(v); 
    } 

    /** Returns whether a node is external. */ 
    public boolean isExternal(Position<E> v) throws InvalidPositionException { 
     TreePosition<E> vv = checkPosition(v); // auxiliary method 
     return (vv.getChildren() == null) || vv.getChildren().isEmpty(); 
    } 

    /** Returns whether a node is the root. */ 
    public boolean isRoot(Position<E> v) throws InvalidPositionException { 
     checkPosition(v); 
     return (v == root()); 
    } 

    /** Returns the root of the tree. */ 
    public Position<E> root() throws EmptyTreeException { 
     if (root == null) 
      throw new EmptyTreeException("The tree is empty"); 
     return root; 
    } 


    /** Returns the parent of a node. */ 
    public Position<E> parent(Position<E> v) throws InvalidPositionException, 
      BoundaryViolationException { 
     TreePosition<E> vv = checkPosition(v); 
     Position<E> parentPos = vv.getParent(); 
     if (parentPos == null) 
      throw new BoundaryViolationException("No parent"); 
     return parentPos; 
    } 

    /** Returns an iterable collection of the children of a node. */ 
    public Iterable<Position<E>> children(Position<E> v) 
      throws InvalidPositionException { 
     TreePosition<E> vv = checkPosition(v); 
     if (isExternal(v)) 
      throw new InvalidPositionException(
        "External nodes have no children"); 
     return vv.getChildren(); 
    } 

    /** Returns an iterable collection of the tree nodes. */ 
    public Iterable<Position<E>> positions() { 
     PositionList<Position<E>> positions = new NodePositionList<Position<E>>(); 
     if (size != 0) 
      preorderPositions(root(), positions); // assign positions in 
                // preorder 
     return positions; 
    } 

    /** Returns an iterator of the elements stored at the nodes */ 
    public Iterator<E> iterator() { 
     Iterable<Position<E>> positions = positions(); 
     PositionList<E> elements = new NodePositionList<E>(); 
     for (Position<E> pos : positions) 
      elements.addLast(pos.element()); 
     return elements.iterator(); // An iterator of elements 
    } 

    /** Replaces the element at a node. */ 
    public E replace(Position<E> v, E o) throws InvalidPositionException { 
     TreePosition<E> vv = checkPosition(v); 
     E temp = v.element(); 
     vv.setElement(o); 
     return temp; 
    } 


    /** Adds a root node to an empty tree */ 
    public Position<E> addRoot(E e) throws NonEmptyTreeException { 
     if (!isEmpty()) 
      throw new NonEmptyTreeException("Tree already has a root"); 
     size = 1; 
     root = createNode(e, null, null); 
     return root; 
    } 

    /** Swap the elements at two nodes */ 
    public void swapElements(Position<E> v, Position<E> w) 
      throws InvalidPositionException { 
     TreePosition<E> vv = checkPosition(v); 
     TreePosition<E> ww = checkPosition(w); 
     E temp = w.element(); 
     ww.setElement(v.element()); 
     vv.setElement(temp); 
    } 


    /** If v is a good tree node, cast to TreePosition, else throw exception */ 
    protected TreePosition<E> checkPosition(Position<E> v) 
      throws InvalidPositionException { 
     if (v == null || !(v instanceof TreePosition)) 
      throw new InvalidPositionException("The position is invalid"); 
     return (TreePosition<E>) v; 
    } 

    /** Creates a new tree node */ 
    protected TreePosition<E> createNode(E element, TreePosition<E> parent, 
      PositionList<Position<E>> children) { 
     return new TreeNode<E>(element, parent, children); 
    } 

    /** 
    * Creates a list storing the the nodes in the subtree of a node, ordered 
    * according to the preorder traversal of the subtree. 
    */ 
    protected void preorderPositions(Position<E> v, 
      PositionList<Position<E>> pos) throws InvalidPositionException { 
     pos.addLast(v); 
     for (Position<E> w : children(v)) 
      preorderPositions(w, pos); // recurse on each child 
    } 

    public Iterator<E> iteratorO() { 
     return null; 
    } 

    public boolean islnternal(Position<E> v) throws InvalidPositionException { 
     return false; 
    } 



    public static void main(String[] args) { 

     LinkedTree<Character> T = new LinkedTree(); 

     // add root 
     T.addRoot('A'); 

     // add children of root 
     T.createNode('B', (TreeNode) (T.root()), new NodePositionList()); 
     TreePosition C = T.createNode('C', (TreeNode) (T.root()), 
       new NodePositionList()); 
     T.createNode('D', (TreeNode) (T.root()), new NodePositionList()); 

     // add children of node C 

     T.createNode('E', C, new NodePositionList()); 
     TreePosition F = T.createNode('F', C, new NodePositionList()); 
     T.createNode('G', C, new NodePositionList()); 

     // add childrn of Node F 
     T.createNode('H', F, new NodePositionList()); 
     T.createNode('I', F, new NodePositionList()); 

     // print out tree 

     System.out.println("Size = " + T.size()); 

    } 

} 

답변

1

심플. size의 값이 적절하게 설정되지 않았습니다. 쓰기 위해 크기에 액세스 할 수있는 곳은 두 곳뿐입니다.

Line 4:  protected int size; // number of nodes 
Line 8:   size = 0; 
Line 12:  public int size() { 
Line 13:   return size; 
Line 18:   return (size == 0); 
Line 69:   if (size != 0) 
Line 97:   size = 1; 
Line 173:   System.out.println("Size = " + T.size()); 

그리고 이것은 당신의 크기() 방법 :

/** Returns the number of nodes in the tree. */ 
public int size() { 
    return size; 
} 

큰 문제가 size은 본질적으로 중복 것 같다. 그러나 요소 수를 결정하기 위해 전체 트리를 구문 분석하지 못하게하므로 캐시로 간주 될 수 있습니다.

지금 당장 경험 한 바와 같이 캐시 및 기타 중복 정보의 일반적인 문제는주의 깊게 추적하고 최신 상태로 유지해야한다는 것입니다. 일부 assert 문구를 전략적으로 배치하면 해당 작업을 수행하는 데 큰 도움이됩니다.

+0

나무의 정확한 높이를 얻을 수 있도록 내 크기 방법을 변경하려면 어떻게 하시겠습니까? – user3701204

+0

두 가지 옵션이 있습니다. 'size'를 완전히 제거하거나 항상 올바른 값을 포함하고 있는지 확인하십시오. 크기를 묻는 것은 O (1)이고, 전체 트리를 반복하는 것은 O (N)입니다. 제작 준비가 된 코드를 가정 할 때 중요한 질문은 (a) N이 얼마나 커질 수 있는지, (b) 얼마나 자주 size()를 호출하고 싶습니까? – JensG

관련 문제