[Data Structure] Sorted Binary Tree

public class SortedBinTree<T extends Comparable> {

    static class Node {
        Object data;
        Node parent;
        Node left;
        Node right;
        public Node(Object data, Node parent, Node left, Node right) {
            this.data = data;
            this.parent = parent;
            this.left = left;
            this.right = right;
        }
        public String toString() {
            return "[data=" + data + "]";
        }
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj.getClass() == Node.class) {
                Node target = (Node)obj;
                return data.equals(target.data)
                        && left == target.left
                        && right == target.right
                        && parent == target.parent;
            }
        }
    }
    private Node root;

    public SortedBinTree() {
        this.root = null;
    }

    public SortedBinTree(T o) {
        this.root = new Node(o, null, null, null);
    }

    /**
     * new node
     * (1) Start the search with the root node as the current node
     * (2) Compare the value of the new node with the value of the current node
     * (3) If the value of the new node is greater, the right child node of the current node is used as the new current node; otherwise, the left child node of the current node is used as the new current node.
     * (4) Repeat steps (2) and (3) until a suitable leaf node is found.
     * (5) Add the new node as a child node of the leaf node found in step (4), if the new node is larger,
     * is added as a right child node; otherwise, added as a left child node.
     */
    public void add(T ele) {
        if (root == null) {
            root = new Node(ele, null, null, null);
        } else {
            Node current = root;
            Node parent  = null;
            int cmp = 0;
            do {
                parent = current;
                cmp = ele.compareTo(current.data);
                if (cmp > 0) {
                    current = current.right;
                } else {
                    current = current.left;
                }
            } while (current != null);
            Node newNode = new Node(ele, parent, null, null);
            if (cmp > 0) {
                parent.right = newNode;
            } else {
                parent.left = newNode;
            }
        }
    }

    /**
     * delete node
     *(1) The node being removed is a leaf node: just remove it from its parent.
     *
     * (2) The deleted node p (non-root node) has only the left subtree: if the deleted node p is the right subtree of its parent node, then let the left subtree pL of p be added to the right subtree of the parent node of p ;
     * The deleted node p is the left subtree of its parent node, then let the left subtree pL of p be added to the left subtree of the parent node of p.
     *
     * (3) The deleted node p (non-root node) has only the right subtree: if the deleted node p is the right subtree of its parent node, then let the right subtree pR of p be added to the right subtree of the parent node of p ;
     * The deleted node p is the left subtree of its parent node, then let the right subtree pR of p be added to the left subtree of the parent node of p.
     *
     * (4) If the left and right subtrees of the deleted node p are not empty, there are two processing methods
     * a. Set pL to the left or right child of p's parent q (depending on whether p is the left or right child of its parent q), and set pR to the right of p's in-order predecessor s child node
     * (s is the bottom right node of pL, which is the largest node in the pL subtree)
     * b. Replace the node pointed to by p with the in-order predecessor or successor of the p node, and then delete the in-order predecessor or successor node from the original sorted binary tree.
     * (i.e. replace p node with the smallest node greater than p or the largest node less than p)
     */
    public void remove(T ele) {
        Node target = getNode(ele);
        if (target == null) {
            return;
        }

        if (target.left == null && target.right == null) { // left and right subtrees are empty
            if (target == root) {
                root = null;
            } else {
                if (target == target.parent.left) {
                    target.parent.left = null;
                } else {
                    target.parent.right = null;
                }
                target.parent = null;
            }
        } else if (target.left == null && target.right != null) { // left subtree is empty, right subtree is not empty
            if (target == root) {
                root = target.right;
            } else {
                if (target == target.parent.left) {
                    // Let the left of the target's parent node point to the right subtree of the target
                    target.parent.left = target.right;
                } else {
                    // Let the right of the parent node of the target point to the right subtree of the target
                    target.parent.right = target.right;
                }
                // Let the parent of the target's right subtree point to the target's parent
                target.right.parent = target.parent;
            }
        } else if (target.left != null && target.right == null) { // left subtree is not empty, right subtree is empty
            if (target == root) {
                root = target.left;
            } else {
                if (target == target.parent.left) {
                    // Let the left of the target's parent node point to the left subtree of the target
                    target.parent.left = target.left;
                } else {
                    // Let the right of the parent node of the target point to the left subtree of the target
                    target.parent.right = target.left;
                }
                // Let the parent of the target's left subtree point to the target's parent
                target.left.parent = target.parent;
            }
        } else if (target.left != null && target.right != null) { // left and right subtrees are not empty
            // leftMaxNode is used to save the node with the largest value in the left subtree of the target node
            Node leftMaxNode = target.left;
            while (leftMaxNode.right != null) {
                leftMaxNode = leftMaxNode.right;
            }
            // delete the leftMaxNode node from the original subtree
            leftMaxNode.parent.right = null;
            // Let the parent of leftMaxNode point to the parent of target
            leftMaxNode.parent = target.parent;
            if (target == target.parent.left) {
                // Let the left of the target's parent node point to leftMaxNode
                target.parent.left = leftMaxNode;
            } else {
                // Let the right of the target's parent node point to leftMaxNode
                target.parent.right = leftMaxNode;
            }
            leftMaxNode.left = target.left;
            leftMaxNode.right = target.right;
            target.parent = target.left = target.right = null;
        }
    }

    // Search for a node based on the given value
    public Node getNode(T ele) {
        Node p = root;
        while (p != null) {
            int cmp = ele.compareTo(p.data);
            if (cmp < 0) {
                p = p.left;
            } else if (cmp > 0) {
                p = p.right;
            } else {
                return p;
            }
        }
        return null;
    }

    // breadth-first traversal
    public List<Node> breadthFirst() {
        Queue<Node> queue = new ArrayDeque<Node>();
        List<Node> list = new ArrayList<Node>();
        if (root != null) {
            // Add the root element to the "queue"
            queue.offer(root);
        }
        while (!queue.isEmpty()) {
            list.add(queue.peek());
            Node p = queue.poll();
            if (p.left != null) {
                queue.offer(p.left);
            }
            if (p.right != null) {
                queue.offer(p.right);
            }
        }
        return list;
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324418415&siteId=291194637