Data structure and algorithm 18 binary sort tree creation, variable, deletion

Keywords: Java

Binary Sort Tree

Binary Search Tree

For any non-leaf node of a binary sorted tree, the value of the left child node is required to be smaller than that of the current node, and the value of the right child node is greater than that of the current node.

If the values are the same, you can place the node in a left or right child node

Creation and traversal of binary sort trees

Medium Order Traversal Binary Sort Tree

package tree.binarysearchtree;

public class BinarySearchTreeDemo01 {
    public static void main(String[] args) {
        int[] arr = {7,3,10,12,5,1,9};
        BinarySortTree binarySortTree = new BinarySortTree();
        // cyclical addition
        for (int i = 0; i < arr.length; i++) {
            binarySortTree.add(new Node(arr[i]));
        }
        System.out.println("infix order ");
        binarySortTree.infixOrder();

    }
}

// create binary search tree
class BinarySortTree{
    private Node root;
    // add
    public void add(Node node){
        if(root==null){
            root = node;
        } else{
            root.add(node);
        }
    }
    // traversal
    public void infixOrder(){
        if(root!=null){
            root.infixOrder();
        } else{
            System.out.println("can not traverse");
        }
    }
}


// create Node
class Node{
    int value;
    Node left;
    Node right;

    public Node(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    // add Node recursively
    public void add(Node node ){
        if(node == null){
            return;
        }
        // determine the relationship of node's value and
        // the value of the root node of the current subtree
        if(node.value<this.value){
            if(this.left==null){
                this.left = node;
            }else{ // If the left subtree of the current node is not empty, add the node recursively to the left
                this.left.add(node);
            }
        } else{ // The value of the added node is greater than that of the current node
            if(this.right==null){
                this.right = node;
            } else{
                this.right.add(node);
            }
        }
    }

    // infix order traversal
    public void infixOrder(){
        if(this.left!=null){
            this.left.infixOrder();
        }
        System.out.println(this.value);
        if(this.right!=null){
            this.right.infixOrder();
        }
    }
}

Deletion of Binary Trees

  1. Delete leaf nodes

    • Find the node targetNode that needs to be deleted first
    • Find the parent of the targetNode (if parent exists)
    • Determine whether targetNode is a parent's left or right child node
    • Delete according to previous situation
    • Left Child NodeParent.left= null;
    • Right Child NodeParent.right= null;
  2. Delete nodes with only one subtree

    • Find the node targetNode that needs to be deleted first

    • Find the parent of the targetNode (if parent exists)

    • Determines whether the child node of targetNode is a left or right child node

    • Is targetNode a parent's left or right child node

    • If the child node of targetNode is a left child node

      • If targetNode is the left child node of parent

        parent.left = targetNode.left

      • If targetNode is the right child node of parent

        Parent.right = targetNode.left

    • If the child node of targetNode is a left child node

      • If targetNode is the left child node of parent

        parent.left = targetNode.right

      • If targetNode is the right child node of parent

        Parent.right = targetNode.right

  3. Delete nodes with two subtrees

    • The node targetNode to be deleted needs to be found first
    • Find parent node of targetNode
    • Find the smallest node (or the largest value of the left subtree) from the right subtree of targetNode
    • Save the value of the smallest node with a temporary variable
    • Delete the smallest node
    • targetNode.value = temp
  1. Find Nodes to Delete
// class Node
// find node wait for deleting

    /**
     *
     * @param value The value of node you wish to delete
     * @return if find it, return this node, or return null
     */
    public Node search(int value){
        if(value==this.value){ // find it
            return this;
        } else if(value<this.value){
            // if value smaller than current node, find it recursively to left side
            // if left node is null, return null
            if(this.left==null){
                return null;
            }
            return this.left.search(value);
        } else{
            // recursively search to right side
            if(this.right==null){
                return null;
            }
            return this.right.search(value);
        }
    }
  1. Find the parent of the node to be deleted
// class Node
// find the parent node of the node to be deleted

    /**
     *
     * @param value the value of node you want to find
     * @return the parent node of the node to be deleted, if not found, return null
     */
    public Node searchParent(int value){
        if((this.left!=null && this.left.value==value) || (this.right!=null && this.right.value==value)){
           return this;
        }else{
            // if value is smaller than current value and left node of current node is not null
            // recursively find left side
            if(value<this.value && this.left!=null){
                this.left.searchParent(value);
            } else if(value >= this.value && this.right!=null){
                this.right.searchParent(value);
            } else{
                return null;
            }
        }
    }
  1. Encapsulate methods to find and parent nodes
// class BinarySortTree
// find node to be deleted
    public Node search(int value){
        if(root==null){
            return null;
        } else{
            return root.search(value);
        }
    }

    // find parent node
    public Node searchParent(int value){
        if(root==null){
            return null;
        } else{
            return root.searchParent(value);
        }
    }
  1. Delete Node
    • Is the root node empty
    • Find the node to delete (determine if it is empty and if the tree has only one root node)
    • Find the parent of the node to be deleted
    • Delete leaf nodes
    • Delete a node with a subtree
    • Delete nodes with two subtrees
      • Find the minimum value of the node's right subtree or the maximum value of the left subtree
      • Find the minimum public int delRightTreeMin(Node node){} of the subtree with node as the root node Delete the minimum node and return the minimum value
// class BinarySortTree
// 1. return the min value of BST with node as the root
    // 2. delete the smallest node of BST with node as the root

    /**
     *
     * @param node Incoming node ( as root node of BST)
     * @return the min value of BST with node as the root
     */
    public int delRightTreeMin(Node node){
        Node target = node;
        // cyclic search left node to find the minimum node
        while(target.left!=null){
            target = target.left;
        }
        // now target is the minimum value
        delete(target.value);
        return target.value;
    }
 // delete node
    public void delete(int value){
        if (root==null){
            return;
        } else{
            // 1. find targetNode (node to be deleted)
            Node targetNode = search(value);
            if(targetNode==null){
                return;
            }
            // if this tree only have one node
            if(root.left==null && root.right==null){
                root = null;
                return;
            }
            // find parent node of targetNode
            Node parent = searchParent(value);

            // if node to be deleted is leaf node
            if(targetNode.left == null && targetNode.right == null){
                // determine target node is right or left node of parent node
                if(parent.left!=null && parent.left.value == value){
                    parent.left = null;
                } else if(parent.right != null && parent.right.value == value){
                    parent.right = null;
                }
            } else if(targetNode.left != null && targetNode.right != null){
                // delete node who has two subtrees
                // find the min value of right tree
                int min = delRightTreeMin(targetNode.right);
                targetNode.value = min;

            } else{ // delete node only with one subtree
                // if node to be deleted has left node
                if(targetNode.left!=null){
                    // if targetNode is left node of parent node
                    if(parent.left.value == value){
                        parent.left = targetNode.left;
                    } else{ // target node is right node of parent node
                        parent.right = targetNode.left;
                    }
                } else{ // node to be deleted has right node
                    // if target node is left node of parent node
                    if(parent.left.value == value){
                        parent.left = targetNode.right;
                    } else{
                        parent.right = targetNode.right;
                    }
                }

            }
        }
    }

test

public static void main(String[] args) {
        int[] arr = {7,3,10,12,5,1,9,2};
        BinarySortTree binarySortTree = new BinarySortTree();
        // cyclical addition
        for (int i = 0; i < arr.length; i++) {
            binarySortTree.add(new Node(arr[i]));
        }
        System.out.println("infix order ");
        binarySortTree.infixOrder();

        System.out.println("\nafter deletion");
        // test delete leaf node
        binarySortTree.delete(7);
        binarySortTree.infixOrder();

output

infix order 
1 2 3 5 7 9 10 12 
after deletion
1 2 3 5 9 10 12 

Complete Code

package tree.binarysearchtree;

import java.util.function.Predicate;

public class BinarySearchTreeDemo01 {
    public static void main(String[] args) {
        int[] arr = {7,3,10,12,5,1,9,2};
        BinarySortTree binarySortTree = new BinarySortTree();
        // cyclical addition
        for (int i = 0; i < arr.length; i++) {
            binarySortTree.add(new Node(arr[i]));
        }
        System.out.println("infix order ");
        binarySortTree.infixOrder();

        System.out.println("\nafter deletion");
        // test delete leaf node
        binarySortTree.delete(7);
        binarySortTree.infixOrder();



    }
}

// create binary search tree
class BinarySortTree{
    private Node root;

    // find node to be deleted
    public Node search(int value){
        if(root==null){
            return null;
        } else{
            return root.search(value);
        }
    }

    // find parent node
    public Node searchParent(int value){
        if(root==null){
            return null;
        } else{
            return root.searchParent(value);
        }
    }

    // 1. return the min value of BST with node as the root
    // 2. delete the smallest node of BST with node as the root

    /**
     *
     * @param node Incoming node ( as root node of BST)
     * @return the min value of BST with node as the root
     */
    public int delRightTreeMin(Node node){
        Node target = node;
        // cyclic search left node to find the minimum node
        while(target.left!=null){
            target = target.left;
        }
        // now target is the minimum value
        delete(target.value);
        return target.value;
    }


    // delete node
    public void delete(int value){
        if (root==null){
            return;
        } else{
            // 1. find targetNode (node to be deleted)
            Node targetNode = search(value);
            if(targetNode==null){
                return;
            }
            // if this tree only have one node
            if(root.left==null && root.right==null){
                root = null;
                return;
            }
            // find parent node of targetNode
            Node parent = searchParent(value);

            // if node to be deleted is leaf node
            if(targetNode.left == null && targetNode.right == null){
                // determine target node is right or left node of parent node
                if(parent.left!=null && parent.left.value == value){
                    parent.left = null;
                } else if(parent.right != null && parent.right.value == value){
                    parent.right = null;
                }
            } else if(targetNode.left != null && targetNode.right != null){
                // delete node who has two subtrees
                // find the min value of right tree
                int min = delRightTreeMin(targetNode.right);
                targetNode.value = min;

            } else{ // delete node only with one subtree
                // if node to be deleted has left node
                if(targetNode.left!=null){
                    // if targetNode is left node of parent node
                    if(parent.left.value == value){
                        parent.left = targetNode.left;
                    } else{ // target node is right node of parent node
                        parent.right = targetNode.left;
                    }
                } else{ // node to be deleted has right node
                    // if target node is left node of parent node
                    if(parent.left.value == value){
                        parent.left = targetNode.right;
                    } else{
                        parent.right = targetNode.right;
                    }
                }

            }
        }
    }


    // add
    public void add(Node node){
        if(root==null){
            root = node;
        } else{
            root.add(node);
        }
    }
    // traversal
    public void infixOrder(){
        if(root!=null){
            root.infixOrder();
        } else{
            System.out.println("can not traverse");
        }
    }
}


// create Node
class Node{
    int value;
    Node left;
    Node right;

    public Node(int value) {
        this.value = value;
    }

    // find node wait for deleting

    /**
     *
     * @param value The value of node you wish to delete
     * @return if find it, return this node, or return null
     */
    public Node search(int value){
        if(value==this.value){ // find it
            return this;
        } else if(value<this.value){
            // if value smaller than current node, find it recursively to left side
            // if left node is null, return null
            if(this.left==null){
                return null;
            }
            return this.left.search(value);
        } else{
            // recursively search to right side
            if(this.right==null){
                return null;
            }
            return this.right.search(value);
        }
    }

    // find the parent node of the node to be deleted

    /**
     *
     * @param value the value of node you want to find
     * @return the parent node of the node to be deleted, if not found, return null
     */
    public Node searchParent(int value){
        if((this.left!=null && this.left.value==value) || (this.right!=null && this.right.value==value)){
           return this;
        }else{
            // if value is smaller than current value and left node of current node is not null
            // recursively find left side
            if(value<this.value && this.left!=null){
                return this.left.searchParent(value);
            } else if(value >= this.value && this.right!=null){
                return this.right.searchParent(value);
            } else{
                return null;
            }
        }
    }


    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    // add Node recursively
    public void add(Node node ){
        if(node == null){
            return;
        }
        // determine the relationship of node's value and
        // the value of the root node of the current subtree
        if(node.value<this.value){
            if(this.left==null){
                this.left = node;
            }else{ // If the left subtree of the current node is not empty, add the node recursively to the left
                this.left.add(node);
            }
        } else{ // The value of the added node is greater than that of the current node
            if(this.right==null){
                this.right = node;
            } else{
                this.right.add(node);
            }
        }
    }

    // infix order traversal
    public void infixOrder(){
        if(this.left!=null){
            this.left.infixOrder();
        }
        System.out.print(this.value+" ");
        if(this.right!=null){
            this.right.infixOrder();
        }
    }
}

Posted by sethadam1 on Fri, 19 Jun 2020 18:54:24 -0700