二叉搜索树

来源:互联网 发布:比较两组数据的差异 编辑:程序博客网 时间:2024/05/17 03:54

简介

二叉搜索树(Binary Search Tree),又被称为二叉查找树。
1.所有非叶子节点至多拥有两个儿子(Left和Right);
2.所有节点存储一个关键字;
3.非叶子节点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;
如:
这里写图片描述

Java实现

/** * 二叉搜索树测试 *  * @author Joe * */public class BinarySearchTreeTest {    public static void main(String[] args) {        Integer[] ints = new Integer[] { 3, 1, 5, 2, 4, 6 };        BinarySearchTree<Integer> bst = new BinarySearchTree<>();        for (Integer d : ints) {            bst.add(d);        }        System.out.print("前序遍历:");        bst.preOrder(bst.getRoot());        System.out.print("\n中序遍历:");        bst.inOrder(bst.getRoot());        System.out.print("\n后序遍历:");        bst.postOrder(bst.getRoot());        System.out.print("\n\n是否包含3节点:" + bst.contains(3));        System.out.print("\n最大节点:" + bst.max());        System.out.print("\n最小节点:" + bst.min());        bst.remove(5);        System.out.print("\n\n删除节点值为5的节点,之后中序遍历:");        bst.inOrder(bst.getRoot());    }}/** * 二叉搜索树(当前节点大于左节点,小于或等于右节点) */class BinarySearchTree<T extends Comparable<? super T>> {    private TreeNode<T> root;    public BinarySearchTree() {        this.root = null;    }    class TreeNode<X> {        private X data;        private TreeNode<X> left;        private TreeNode<X> right;        public TreeNode(X data) {            this.data = data;            this.left = null;            this.right = null;        }    }    public TreeNode<T> getRoot() {        return root;    }    /**     * 添加节点     * @param t     */    public void add(T t) {        if (root == null) {            root = new TreeNode<T>(t);        }        else {            add(t, root);        }    }    private void add(T t, TreeNode<T> node) {        if (node.data.compareTo(t) > 0) {            if (node.left == null) {                node.left = new TreeNode<T>(t);            }            else {                add(t, node.left);            }        }        else {            if (node.right == null) {                node.right = new TreeNode<T>(t);            }            else {                add(t, node.right);            }        }    }    /**     * 前序遍历     *      * @param node     */    public void preOrder(TreeNode<T> node) {        if (node != null) {            System.out.print(node.data);            preOrder(node.left);            preOrder(node.right);        }    }    /**     * 中序遍历     *      * @param node     */    public void inOrder(TreeNode<T> node) {        if (node != null) {            inOrder(node.left);            System.out.print(node.data);            inOrder(node.right);        }    }    /**     * 后序遍历     *      * @param node     */    public void postOrder(TreeNode<T> node) {        if (node != null) {            postOrder(node.left);            postOrder(node.right);            System.out.print(node.data);        }    }    /**     * 是否包含节点     *      * @param t     * @return     */    public boolean contains(T t) {        return contains(t, root);    }    private boolean contains(T t, TreeNode<T> node) {        if (node == null)            return false;        if (node.data.compareTo(t) > 0)            return contains(t, node.left);        else if (node.data.compareTo(t) < 0)            return contains(t, node.right);        else            return true;    }    /**     * 查询最大节点     *      * @param node     * @return     */    public T max() {        TreeNode<T> node = root;        if (node != null) {            while (node.right != null)                node = node.right;        }        return node == null ? null : node.data;    }    /**     * 查询最小节点     *      * @param node     * @return     */    public T min() {        return min(root);    }    private T min(TreeNode<T> node) {        if (node != null) {            while (node.left != null)                node = node.left;        }        return node == null ? null : node.data;    }    /**     * 删除某个节点     *      * @param t     */    public void remove(T t) {        root = remove(t, root);    }    /**     * 删除操作,首先找到删除节点,再分以下三种情况:     * 1.如果节点左右子树都包含,找到当前节点右子树最小值,赋值给当前节点,并递归删除右子树最小值     * 2.如果节点只包含左子树或右子树之一,将其设置为父节点即可     * 3.如果节点没有左右子树,直接删除即可     *      * @param t     * @param node     * @return     */    private TreeNode<T> remove(T t, TreeNode<T> node) {        if (node == null)            return node;        if (node.data.compareTo(t) > 0)            node.left = remove(t, node.left);        else if (node.data.compareTo(t) < 0)            node.right = remove(t, node.right);        else {            // 找到删除节点之后            if (node.left != null && node.right != null) {// 情况1                node.data = min(node.right);                node.right = remove(node.data, node.right);            }            else {// 情况23                node = (node.left != null) ? node.left : node.right;            }        }        return node;    }}

打印结果:

前序遍历:312546
中序遍历:123456
后序遍历:214653

是否包含3节点:true
最大节点:6
最小节点:1

删除节点值为5的节点,之后中序遍历:12346

备注:

二叉搜索树的中序遍历是有序的

0 0
原创粉丝点击