用Java创建最小二叉搜索树(BST)

时间:2015-07-02 21:55:38

标签: java recursion data-structures binary-search-tree

我正在使用二叉搜索树,并尝试编写一个从数组值创建最小BST的方法。但是,它没有成功运作。我在哪里弄错了?它应使用 inOrderTraverseTree 方法以升序打印值。我保留了一些额外的方法,如果可能感觉无关紧要,可以删除。

我更新了相关代码,但是,我仍然需要让根节点调用 inOrderTraversal(节点根目录)方法。

BinaryTree.java

class Node {

    int key;

    Node leftChild;
    Node rightChild;

    Node(int key) {
        this.key = key;
    }
Node (){}

    public String toString() {

        return "\n"+key+" ";
    }
}



public class BinaryTree {

    Node root;

    BinaryTree (){
        root = null;
    }

    public void addNode(int key) {

        Node newNode = new Node(key);

        // If there is no root this becomes root
        if (root == null) {
            root = newNode;
        } 


        else {

            // Set root as the Node we will start
            // with as we traverse the tree

            Node focusNode = root;
            Node parent;

            while (true) {

                parent = focusNode;

                if (key < focusNode.key) {

                    focusNode = focusNode.leftChild;

                    if (focusNode == null) {

                        parent.leftChild = newNode;
                        return; // All Done
                    }
                } // end of if 

                else { 

                    focusNode = focusNode.rightChild;

                    if (focusNode == null) {

                        parent.rightChild = newNode;
                        return; 
                    }
                }
            }
        }
    }

    // get the height of binary tree 
    public int height(Node root) {

        if (root == null)
            return -1;

        Node focusNode = root; 
        int leftHeight = focusNode.leftChild != null ? height( focusNode.leftChild) : 0;
        int rightHeight = focusNode.rightChild != null ? height( focusNode.rightChild) : 0;
        return 1 + Math.max(leftHeight, rightHeight);
    }

    // METHODS FOR THE TREE TRAVERSAL

    // inOrderTraverseTree : i) X.left ii) X iii) X.right
    public void inOrderTraverseTree(Node focusNode) {

        if (focusNode != null) {

            inOrderTraverseTree(focusNode.leftChild);
            // System.out.println(focusNode);
            System.out.print( focusNode );
            inOrderTraverseTree(focusNode.rightChild);
        }
        // System.out.println();
    }

    // preOrderTraverseTree : i) X ii) X.left iii) X.right
    public void preorderTraverseTree(Node focusNode) {

        if (focusNode != null) {

            System.out.println(focusNode);
            preorderTraverseTree(focusNode.leftChild);
            preorderTraverseTree(focusNode.rightChild);

        }
    }

    // postOrderTraverseTree : i) X.left ii) X.right iii) X
    public void postOrderTraverseTree(Node focusNode) {

        if (focusNode != null) {

            preorderTraverseTree(focusNode.leftChild);
            preorderTraverseTree(focusNode.rightChild);
            System.out.println(focusNode);

        }
    }
    // END 


    public Node findNode(int key) {

        Node focusNode = root;

        while (focusNode.key != key) {

            if (key < focusNode.key) {

                focusNode = focusNode.leftChild;

            } else {

                focusNode = focusNode.rightChild;
            }

            if (focusNode == null)
                return null;
        }
        return focusNode;

    }


    public boolean remove(int key) {

        Node focusNode = root;
        Node parent = root;
        boolean isItALeftChild = true;


        // we will remove the focusNode 
        while (focusNode.key != key) {

            parent = focusNode;

            if (key < focusNode.key) {

                isItALeftChild = true;
                focusNode = focusNode.leftChild;
            } 

            else {

                isItALeftChild = false;
                focusNode = focusNode.rightChild;
            }

            if (focusNode == null)
                return false;
        }

        // no child 
        if (focusNode.leftChild == null && focusNode.rightChild == null) {

            if (focusNode == root)
                root = null;

            else if (isItALeftChild)
                parent.leftChild = null;

            else
                parent.rightChild = null;
        }

        // one child ( left child )
        else if (focusNode.rightChild == null) {

            if (focusNode == root)
                root = focusNode.leftChild;

            else if (isItALeftChild)
                parent.leftChild = focusNode.leftChild;

            else
                parent.rightChild = focusNode.leftChild;
        }


        else if (focusNode.leftChild == null) {

            if (focusNode == root)
                root = focusNode.rightChild;

            else if (isItALeftChild)
                parent.leftChild = focusNode.rightChild;

            else
                parent.rightChild = focusNode.rightChild;

        }

        // two children exits 
        else {

            // replacement is the smallest node in the right subtree 
            // we neeed to delete the focusNode 
            Node replacement = getReplacementNode(focusNode);

            if (focusNode == root)
                root = replacement;

            else if (isItALeftChild)
                parent.leftChild = replacement;

            else
                parent.rightChild = replacement;

            replacement.leftChild = focusNode.leftChild;
        }

        return true;
    }



    public Node getReplacementNode(Node replacedNode) {

        Node replacementParent = replacedNode;
        Node replacement = replacedNode;
        Node focusNode = replacedNode.rightChild;

        // find the smallest node of the right subtree of the node to be deleted 
        while (focusNode != null) {

            replacementParent = replacement;
            replacement = focusNode;
            focusNode = focusNode.leftChild;
        }

        // exit when the focusNode is null
        // the replacement is the smallest of the right subtree

        if (replacement != replacedNode.rightChild) {

            replacementParent.leftChild = replacement.rightChild;
            replacement.rightChild = replacedNode.rightChild;
        }

        return replacement;
    }

private  void createMinimalBST(int arr[], int start, int end, Node newNode){

        if ( end <= start )
            return;
        int mid = (start + end) / 2;
        newNode.key = arr[mid];

        if ( root == null ){
            root = newNode;
        }

        System.out.println("new node = "+ newNode );

        if (start <= mid-1) {
            newNode.leftChild = new Node();
            createMinimalBST(arr, start, mid - 1, newNode.leftChild);
        }
        if (mid+1 <= end) {
            newNode.rightChild = new Node();
            createMinimalBST(arr, mid + 1, end, newNode.rightChild); 
        }
        // System.out.println("left child = "+ newNode.leftChild +" "+ " right child = "+ newNode.rightChild);

    } 

    public void createMinimalBST(int array[]) {

        Node n = new Node();

        createMinimalBST(array, 0, array.length - 1, n);
    }

            public static void main(String[] args) {

        int[] myArr = { 1,2,3,4,5,6,7,8,9 }; // sortedArrayToBST
        BinaryTree myTr = new BinaryTree();
        // Node n = BinaryTree.createMinimalBST(myArr);
        myTr.createMinimalBST(myArr);

        // System.out.println("The root is = "+myTr.root);
        // myTr.inOrderTraverseTree(myTr.root);
        System.out.println();
        myTr.inOrderTraverseTree(myTr.root);

    }

    }

1 个答案:

答案 0 :(得分:1)

您需要将createMinimalBST()的结果分配给变量。

此方法返回一个节点:

 public Node createMinimalBST(int array[]) {...}

然而,主要是......

 myTr.createMinimalBST(myArr);

您调用该方法但没有变量尝试保存结果。

此外,您可能希望将createMinialBST设置为公共静态,并将其命名为:

  

myTr = BinaryTree.createMinimalBST(myArr);

此外,还有两种方法可以完成这项工作:

1)将createMinimalBST()移动到Node中,以便在键将就地设置时发生递归。

private  void createMinimalBST(int arr[], int start, int end){
    int mid = (start + end) / 2;
    this.key = arr[mid];

    System.out.println("new node = "+n);


    if (start <= mid-1) {
        this.leftChild = new Node();
        this.leftChild.createMinimalBST(arr, start, mid - 1);
    } 
    if (mid+1 <= end) {
        this.rightChild = new Node();
        this.rightChild.createMinimalBST(arr, mid + 1, end); 
    } 
    System.out.println("left child = "+ newNode.leftChild +" "+ " right child = "+ newNode.rightChild);
}  

2)如果您希望该方法保留在BinaryTree中,您可以考虑将Node作为参数传入createMinimalBST()ilke createMinimalBST(arr,node);

private  void createMinimalBST(int arr[], int start, int end, Node newNode){
    int mid = (start + end) / 2;
    newNode.key = arr[mid];

    System.out.println("new node = "+n);


    if (start <= mid-1) {
        newNode.leftChild = new Node();
        createMinimalBST(arr, start, mid - 1, newNode.leftChild);
    }
    if (mid+1 <= end) {
        newNode.rightChild = new Node();
        createMinimalBST(arr, mid + 1, end, newNode.leftChild); 
    }
    System.out.println("left child = "+ newNode.leftChild +" "+ " right child = "+ newNode.rightChild);
}