按字母顺序打印树数据结构

时间:2014-11-29 15:30:55

标签: java algorithm data-structures tree

作为数据结构和算法的练习,我有一项重要任务,其中一部分是修改此树数据结构以按字母顺序打印树。我不会发布整个任务,因为它是巨大。我卡在最后一部分,要求我修改给定的树数据结构,以按字母顺序打印树。我坚持了几天,很简单,不知道该怎么做。任何帮助都会得到满足,谢谢。我的意见是我必须以某种方式修改printTreeRecursive()方法。

例如,当前数据结构将打印如下树:

c: d c b a

(最后添加的第一个孩子)。

其中c:是根,d c b a是他的孩子

但我应该修改它看起来像这样:

c: a b c d

这是数据结构:

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

    // SLLNode is the implementation of the Node interface
    class SLLNode<P> implements Node<P> {

        // Holds the links to the needed nodes
        SLLNode<P> parent, sibling, firstChild;

        // Hold the data
        P element;

        public SLLNode(P o) {
            element = o;
            parent = sibling = firstChild = null;
        }

        public P getElement() {
            return element;
        }

        public void setElement(P o) {
            element = o;
        }

    }

    protected SLLNode<E> root;

    public SLLTree() {
        root = null;
    }

    public Node<E> root() {
        return root;
    }

    public Tree.Node<E> parent(Tree.Node<E> node) {
        return ((SLLNode<E>) node).parent;
    }

    public int childCount(Tree.Node<E> node) {
        SLLNode<E> tmp = ((SLLNode<E>) node).firstChild;
        int num = 0;
        while (tmp != null) {
            tmp = tmp.sibling;
            num++;
        }
        return num;
    }

    public void makeRoot(E elem) {
        root = new SLLNode<E>(elem);
    }

    public Node<E> addChild(Node<E> node, E elem) {
        SLLNode<E> tmp = new SLLNode<E>(elem);
        SLLNode<E> curr = (SLLNode<E>) node;
        tmp.sibling = curr.firstChild;
        curr.firstChild = tmp;
        tmp.parent = curr;
        return tmp;
    }

    public void remove(Tree.Node<E> node) {
        SLLNode<E> curr = (SLLNode<E>) node;
        if (curr.parent != null) {
            if (curr.parent.firstChild == curr) {
                // The node is the first child of its parent
                // Reconnect the parent to the next sibling
                curr.parent.firstChild = curr.sibling;
            } else {
                // The node is not the first child of its parent
                // Start from the first and search the node in the sibling list
                // and remove it
                SLLNode<E> tmp = curr.parent.firstChild;
                while (tmp.sibling != curr) {
                    tmp = tmp.sibling;
                }
                tmp.sibling = curr.sibling;
            }
        } else {
            root = null;
        }
    }

    class SLLTreeIterator<T> implements Iterator<T> {

        SLLNode<T> start, current;

        public SLLTreeIterator(SLLNode<T> node) {
            start = node;
            current = node;
        }

        public boolean hasNext() {
            return (current != null);
        }

        public T next() throws NoSuchElementException {
            if (current != null) {
                SLLNode<T> tmp = current;
                current = current.sibling;
                return tmp.getElement();
            } else {
                throw new NoSuchElementException();
            }
        }

        public void remove() {
            if (current != null) {
                current = current.sibling;
            }
        }
    }

    public Iterator<E> children(Tree.Node<E> node) {
        return new SLLTreeIterator<E>(((SLLNode<E>) node).firstChild);
    }

    void printTreeRecursive(Node<E> node, int level) {
        if (node == null)
            return;
        int i;
        SLLNode<E> tmp;

        for (i = 0; i < level; i++)
            System.out.print("  ");
        System.out.println(node.getElement().toString());
        tmp = ((SLLNode<E>) node).firstChild;

        while (tmp != null) {
            printTreeRecursive(tmp, level + 1);
            tmp = tmp.sibling;
        }
    }

    public void printTree() {
        printTreeRecursive(root, 0);
    }

    public int countMaxChildren() {
        return countMaxChildrenRecursive(root);
    }

    int countMaxChildrenRecursive(SLLNode<E> node) {
        int t = childCount(node);
        SLLNode<E> tmp = node.firstChild;
        while (tmp != null) {
            t = Math.max(t, countMaxChildrenRecursive(tmp));
            tmp = tmp.sibling;
        }
        return t;
    }

}
public interface Tree<E> {
    // //////////Accessors ////////////

    public Tree.Node<E> root();

    public Tree.Node<E> parent(Tree.Node<E> node);

    public int childCount(Tree.Node<E> node);

    // //////////Transformers ////////////
    public void makeRoot(E elem);

    public Tree.Node<E> addChild(Tree.Node<E> node, E elem);

    public void remove(Tree.Node<E> node);

    // //////////Iterator ////////////
    public Iterator<E> children(Tree.Node<E> node);

    // //////Inner interface for tree nodes ////////
    public interface Node<E> {

        public E getElement();

        public void setElement(E elem);

    }
}
public class SLLTreeTest {

public static void main(String[] args) {

    Tree.Node<String> a, b, c, d;

    SLLTree<String> t = new SLLTree<String>();

    t.makeRoot("C:");

    a = t.addChild(t.root, "Program files");
    b = t.addChild(a, "CodeBlocks");
    c = t.addChild(b, "codeblocks.dll");
    c = t.addChild(b, "codeblocks.exe");
    b = t.addChild(a, "Nodepad++");
    c = t.addChild(b, "langs.xml");
    d = c;
    c = t.addChild(b, "readme.txt");
    c = t.addChild(b, "notepad++.exe");
    a = t.addChild(t.root, "Users");
    b = t.addChild(a, "Darko");
    c = t.addChild(b, "Desktop");
    c = t.addChild(b, "Downloads");
    c = t.addChild(b, "My Documents");
    c = t.addChild(b, "My Pictures");
    b = t.addChild(a, "Public");
    a = t.addChild(t.root, "Windows");
    b = t.addChild(a, "Media");

    t.printTree();

    t.remove(d);
    t.printTree();

    System.out.println("The maximum number of children is "
            + t.countMaxChildren());

}

}

1 个答案:

答案 0 :(得分:0)

正如我所见,我的初步建议对于提问者和其他评论者来说也足够好了。所以,由于这是一项学习任务,我不会把代码写成答案(我会把所有的乐趣都带走,不是吗?)。我将分享一些重要的检查点,以便在思考过程中实现,如果达到这个目标应该导致解决方案:

  • 我们需要Collection
  • 我们需要使用广度优先遍历(printTreeRecursive是一个很好的例子)
  • 我们需要查看while的{​​{1}}周期,因为它是实现遍历的关键
  • 每当我们到达printTreeRecursive时,我们都应该insert sort节点进入集合
  • 在遍历之后,我们迭代node并打印出其元素