【问题标题】:whats wrong with my implementation of Tree in java我在 java 中实现 Tree 有什么问题
【发布时间】:2014-06-22 00:04:45
【问题描述】:

我正在尝试实现一个包含给定节点的子节点列表的树。当我尝试在我的 main 方法中输出大小时,它返回 1。任何人都可以查看我的 createNode 方法是否有任何问题?在任何人生气之前,我只是将我的所有代码都包含在内,这样你就可以看到我正在尝试做什么:)

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

    }

}

【问题讨论】:

    标签: java data-structures tree linked-list


    【解决方案1】:

    简单。 size 的值设置不充分。只有两个地方可以访问 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());
    

    这是你的 size() 方法:

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

    主要问题似乎是size 本质上是多余的。但是,它会阻止您解析整个树以确定元素计数,因此可以将其视为缓存。

    正如您现在所经历的,缓存和其他冗余信息的普遍问题是,您需要仔细跟踪它们并使其保持最新状态。战略性地放置一些assert 语句可以极大地帮助您完成这项任务。

    【讨论】:

    • 你会建议在我的尺寸方法中进行哪些更改,以便我可以得到正确的树高度?
    • 两个选项。要么完全删除size,要么确保它始终包含正确的值。问size 是 O(1),而迭代整个树是 O(N)。假设代码可用于生产,关键问题是 (a) 您的 N 可能会变得多大以及 (b) 您希望多久调用一次 size()?
    猜你喜欢
    • 1970-01-01
    • 2019-06-07
    • 2021-07-25
    • 2011-09-08
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    相关资源
    最近更新 更多