通过公共API导出非公共类型

时间:2010-04-17 20:30:03

标签: oop warnings

我正在尝试关注树木教程:http://cslibrary.stanford.edu/110/BinaryTrees.html 这是我到目前为止编写的代码:

package trees.bst;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

/**
 *
 * @author sachin
 */
public class BinarySearchTree {

    Node root = null;

    class Node {

        Node left = null;
        Node right = null;
        int data = 0;

        public Node(int data) {
            this.left = null;
            this.right = null;
            this.data = data;
        }
    }

    public void insert(int data) {
        root = insert(data, root);
    }

    public boolean lookup(int data) {
        return lookup(data, root);
    }

    public void buildTree(int numNodes) {
        for (int i = 0; i < numNodes; i++) {
            int num = (int) (Math.random() * 10);
            System.out.println("Inserting number:" + num);
            insert(num);
        }
    }

    public int size() {
        return size(root);
    }

    public int maxDepth() {
        return maxDepth(root);
    }

    public int minValue() {
        return minValue(root);
    }

    public int maxValue() {
        return maxValue(root);
    }

    public void printTree() {   //inorder traversal
        System.out.println("inorder traversal:");
        printTree(root);
        System.out.println("\n--------------");
    }

    public void printPostorder() {   //inorder traversal
        System.out.println("printPostorder traversal:");
        printPostorder(root);
        System.out.println("\n--------------");
    }

    public int buildTreeFromOutputString(String op) {
        root = null;
        int i = 0;
        StringTokenizer st = new StringTokenizer(op);
        while (st.hasMoreTokens()) {
            String stNum = st.nextToken();
            int num = Integer.parseInt(stNum);
            System.out.println("buildTreeFromOutputString: Inserting number:" + num);
            insert(num);
            i++;
        }
        return i;
    }

    public boolean hasPathSum(int pathsum) {
        return hasPathSum(pathsum, root);
    }

    public void mirror() {
        mirror(root);
    }

    public void doubleTree() {
        doubleTree(root);
    }

    public boolean sameTree(BinarySearchTree bst) { //is this tree same as another given tree?
        return sameTree(this.root, bst.getRoot());
    }

    public void printPaths() {
        if (root == null) {
            System.out.println("print path sum: tree is empty");
        }

        List pathSoFar = new ArrayList();
        printPaths(root, pathSoFar);

    }

    ///-------------------------------------------Public helper functions
    public Node getRoot() {
        return root;
    }
    //Exporting a non public Type through public API
    ///-------------------------------------------Helper Functions

    private boolean isLeaf(Node node) {
        if (node == null) {
            return false;
        }
        if (node.left == null && node.right == null) {
            return true;
        }
        return false;
    }

    ///-----------------------------------------------------------
    private boolean sameTree(Node n1, Node n2) {
        if ((n1 == null && n2 == null)) {
            return true;
        } else {
            if ((n1 == null || n2 == null)) {
                return false;
            } else {
                if ((n1.data == n2.data)) {
                    return (sameTree(n1.left, n2.left) && sameTree(n1.right, n2.right));
                }
            }
        }

        return false;


    }

    private void doubleTree(Node node) {
        //create a copy
        //bypass the copy to continue looping
        if (node == null) {
            return;
        }
        Node copyNode = new Node(node.data);
        Node temp = node.left;
        node.left = copyNode;
        copyNode.left = temp;
        doubleTree(copyNode.left);
        doubleTree(node.right);
    }

    private void mirror(Node node) {
        if (node == null) {
            return;
        }
        Node temp = node.left;
        node.left = node.right;
        node.right = temp;
        mirror(node.left);
        mirror(node.right);
    }

    private void printPaths(Node node, List pathSoFar) {
        if (node == null) {
            return;
        }
        pathSoFar.add(node.data);
        if (isLeaf(node)) {
            System.out.println("path in tree:" + pathSoFar);
            pathSoFar.remove(pathSoFar.lastIndexOf(node.data)); //only the current node, a node.data may be duplicated
            return;
        } else {
            printPaths(node.left, pathSoFar);
            printPaths(node.right, pathSoFar);
        }
    }

    private boolean hasPathSum(int pathsum, Node node) {
        if (node == null) {
            return false;
        }
        int val = pathsum - node.data;
        boolean ret = false;
        if (val == 0 && isLeaf(node)) {
            ret = true;
        } else if (val == 0 && !isLeaf(node)) {
            ret = false;
        } else if (val != 0 && isLeaf(node)) {
            ret = false;
        } else if (val != 0 && !isLeaf(node)) {
            //recurse further
            ret = hasPathSum(val, node.left) || hasPathSum(val, node.right);
        }

        return ret;

    }

    private void printPostorder(Node node) {  //inorder traversal
        if (node == null) {
            return;
        }
        printPostorder(node.left);
        printPostorder(node.right);
        System.out.print(" " + node.data);

    }

    private void printTree(Node node) {  //inorder traversal
        if (node == null) {
            return;
        }
        printTree(node.left);
        System.out.print(" " + node.data);
        printTree(node.right);
    }

    private int minValue(Node node) {
        if (node == null) {
            //error case: this is not supported
            return -1;
        }
        if (node.left == null) {
            return node.data;
        } else {
            return minValue(node.left);
        }
    }

    private int maxValue(Node node) {
        if (node == null) {
            //error case: this is not supported
            return -1;
        }
        if (node.right == null) {
            return node.data;
        } else {
            return maxValue(node.right);
        }
    }

    private int maxDepth(Node node) {
        if (node == null || (node.left == null && node.right == null)) {
            return 0;
        }
        int ldepth = 1 + maxDepth(node.left);
        int rdepth = 1 + maxDepth(node.right);

        if (ldepth > rdepth) {
            return ldepth;
        } else {
            return rdepth;
        }
    }

    private int size(Node node) {
        if (node == null) {
            return 0;
        }
        return 1 + size(node.left) + size(node.right);

    }

    private Node insert(int data, Node node) {
        if (node == null) {
            node = new Node(data);

        } else if (data <= node.data) {
            node.left = insert(data, node.left);
        } else {
            node.right = insert(data, node.right);
        }
        //control should never reach here;

        return node;
    }

    private boolean lookup(int data, Node node) {
        if (node == null) {
            return false;
        }
        if (node.data == data) {
            return true;
        }
        if (data < node.data) {
            return lookup(data, node.left);
        } else {
            return lookup(data, node.right);
        }
    }

    public static void main(String[] args) {
        BinarySearchTree bst = new BinarySearchTree();
        int treesize = 5;
        bst.buildTree(treesize);
        //treesize = bst.buildTreeFromOutputString("4 4 4 6 7");
        treesize = bst.buildTreeFromOutputString("3 4 6 3 6");
        //treesize = bst.buildTreeFromOutputString("10");
        for (int i = 0; i < treesize; i++) {
            System.out.println("Searching:" + i + " found:" + bst.lookup(i));
        }
        System.out.println("tree size:" + bst.size());
        System.out.println("maxDepth :" + bst.maxDepth());
        System.out.println("minvalue :" + bst.minValue());
        System.out.println("maxvalue :" + bst.maxValue());
        bst.printTree();
        bst.printPostorder();
        int pathSum = 10;
        System.out.println("hasPathSum " + pathSum + ":" + bst.hasPathSum(pathSum));
        pathSum = 6;
        System.out.println("hasPathSum " + pathSum + ":" + bst.hasPathSum(pathSum));
        pathSum = 19;
        System.out.println("hasPathSum " + pathSum + ":" + bst.hasPathSum(pathSum));
        bst.printPaths();

        bst.printTree();
       //bst.mirror();
        System.out.println("Tree after mirror function:");
        bst.printTree();
        //bst.doubleTree();
        System.out.println("Tree after double function:");
        bst.printTree();
        System.out.println("tree size:" + bst.size());

        System.out.println("Same tree:" + bst.sameTree(bst));
        BinarySearchTree bst2 = new BinarySearchTree();
        bst2.buildTree(treesize);
        treesize = bst2.buildTreeFromOutputString("3 4 6 3 6");
        bst2.printTree();
        System.out.println("Same tree:" + bst.sameTree(bst2));
        System.out.println("---");
    }
}

现在问题是netbeans显示警告:通过公共API为函数getRoot()导出非公共类型。 我编写这个函数来获取在sameTree()函数中使用的树的根,以帮助比较“this”和给定的树。 也许这是一个OOP设计问题......我应该如何重构上面的代码,我没有得到这个警告,我在这里缺少什么概念?


2 个答案:

答案 0 :(得分:1)

这里的问题是某些代码可能会调用getRoot()但是无法使用它的返回值,因为您只提供了对Node类的包访问。

使Node成为具有自己文件的顶级课程,或者至少将其公开

答案 1 :(得分:0)

我真的不明白为什么你甚至创建了getRoot()方法。只要您在班级内,您甚至可以从同一班级的任何其他对象访问私有字段。

所以你可以改变

public boolean sameTree(BinarySearchTree bst) { //is this tree same as another given tree?
    return sameTree(this.root, bst.getRoot());
}

public boolean sameTree(BinarySearchTree bst) { //is this tree same as another given tree?
    return sameTree(this.root, bst.root);
}

对于将同一个实例传递给此方法的情况,我还会添加一个“短路径”:

public boolean sameTree(BinarySearchTree bst) { //is this tree same as another given tree?
    if (this == bst) {
        return true;
    }
    return sameTree(this.root, bst.root);
}