【数据结构】排序二叉树

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);
    }

    /**
     *  新增节点
     * (1)以根节点为当前节点开始搜索
     * (2)拿新节点的值和当前节点的值比较
     * (3)如果新节点的值更大,则以当前节点的右子节点作为新的当前节点;否则以当前节点的左子节点作为新的当前节点。
     * (4)重复(2),(3)两个步骤,直到搜索到合适的叶子节点。
     * (5)将新节点添加为第(4)步找到的叶子节点的子节点,如果新节点更大,
     *      则添加为右子节点;否则,加为左子节点。
     */
    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;
            }
        }
    }

    /**
     *   删除节点
     *  (1)被删除的节点是叶子节点:只需将它从其父节点中删除。
     *
     *  (2)被删除节点p(非根节点)只有左子树:若被删除节点p是其父节点的右子树,则让p的左子树pL添加成p的父节点的右子树;
     *      被删除节点p是其父节点的左子树,则让p的左子树pL添加成p的父节点的左子树。
     *
     *  (3)被删除节点p(非根节点)只有右子树:若被删除节点p是其父节点的右子树,则让p的右子树pR添加成p的父节点的右子树;
     *      被删除节点p是其父节点的左子树,则让p的右子树pR添加成p的父节点的左子树。
     *
     *  (4)若被删除节点p的左、右子树均非空,处理方式有两种
     *      a、将pL设为p的父节点q的左或右子节点(取决于p是其父节点q的左、右子节点),将pR设为p节点的中序前趋节点s的右子节点
     *      (s是pL最右下的节点,也就是pL子树中最大的节点)
     *      b、以p节点的中序前趋或后继替代p所指节点,然后在从原排序二叉树中删去中序前趋或后继节点。
     *      (即用大于p的最小节点或小于p的最大节点代替p节点)
     */
    public void remove(T ele) {
        Node target = getNode(ele);
        if (target == null) {
            return;
        }

        if (target.left == null && target.right == null) { // 左、右子树为空
            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) { // 左子树为空,右子树不为空
            if (target == root) {
                root = target.right;
            } else {
                if (target == target.parent.left) {
                    // 让target的父节点的left指向target的右子树
                    target.parent.left = target.right;
                } else {
                    // 让target的父节点的right指向target的右子树
                    target.parent.right = target.right;
                }
                // 让target的右子树的parent指向target的parent
                target.right.parent = target.parent;
            }
        } else if (target.left != null && target.right == null) { // 左子树不为空,右子树为空
            if (target == root) {
                root = target.left;
            } else {
                if (target == target.parent.left) {
                    // 让target的父节点的left指向target的左子树
                    target.parent.left = target.left;
                } else {
                    // 让target的父节点的right指向target的左子树
                    target.parent.right = target.left;
                }
                // 让target的左子树的parent指向target的parent
                target.left.parent = target.parent;
            }
        } else if (target.left != null && target.right != null) { // 左、右子树不为空
            // leftMaxNode用于保存target节点的左子树中值最大的节点
            Node leftMaxNode = target.left;
            while (leftMaxNode.right != null) {
                leftMaxNode = leftMaxNode.right;
            }
            // 从原来子树中删除leftMaxNode节点
            leftMaxNode.parent.right = null;
            // 让leftMaxNode的parent指向target的parent
            leftMaxNode.parent = target.parent;
            if (target == target.parent.left) {
                // 让target的父节点的left指向leftMaxNode
                target.parent.left = leftMaxNode;
            } else {
                // 让target的父节点的right指向leftMaxNode
                target.parent.right = leftMaxNode;
            }
            leftMaxNode.left = target.left;
            leftMaxNode.right = target.right;
            target.parent = target.left = target.right = null;
        }
    }

    // 根据给定的值搜索节点
    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;
    }

    // 广度优先遍历
    public List<Node> breadthFirst() {
        Queue<Node> queue = new ArrayDeque<Node>();
        List<Node> list = new ArrayList<Node>();
        if (root != null) {
            // 将根元素加入"队列"
            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;
    }
}

猜你喜欢

转载自my.oschina.net/u/3545495/blog/1795213