Java实现 二叉搜索树算法(BST)

Java实现 二叉搜索树算法(BST)
树是由节点和边构成,储存元素的集合。节点分根节点、父节点和子节点的概念。二叉树binary tree,则加了“二叉”(binary),意思是在树中作区分。 每个节点至多有两个子(child),left child & right child。二叉树在很多例子中使用,比如二叉树表示算术表达式。 其要求:每个节点比其左子树元素大,比其右子树元素小。
1、对其节点的増差删:

package com.cxg.demo.test.tree;
/**
 * Title: Java实现 二叉搜索树算法(BST)</br>
 * 树是由节点和边构成,储存元素的集合。节点分根节点、父节点和子节点的概念。
 * 二叉树binary tree,则加了“二叉”(binary),意思是在树中作区分。
 * 每个节点至多有两个子(child),left child & right child。
 * 二叉树在很多例子中使用,比如二叉树表示算术表达式。
 * 其要求:每个节点比其左子树元素大,比其右子树元素小。
 * Description: TestDemo</br>
 * @author xg.c
 * @date 2016年7月26日 上午10:11:37
 */
public class BinarySearchTree {
    //常量之根节点
    public static TreeNode root;
    public BinarySearchTree() {
        this.root = null;
    }
    /**
     * Title: 打印二叉树</br>
     * Description: TestDemo</br>
     * @author xg.c
     * @date 2016年7月26日 上午10:53:13
     * @param root
     */
    public void toString(TreeNode root) {
        if (root != null) {
            toString(root.left);
            System.out.print("value = " + root.value + " -> ");
            toString(root.right);
        }
    }
    /**
     * Title: 添加节点</br>
     * 要求:每个节点比其左子树元素大,比其右子树元素小。</br>
     * 步骤:
     * 1. 从root节点开始
     * 2. 如果root为空,root为插入值
     * 循环:
     * 3. 如果当前节点值大于插入值,找左节点
     * 4. 如果当前节点值小于插入值,找右节点
     * Description: TestDemo</br>
     * @author xg.c
     * @date 2016年7月26日 上午10:25:08
     * @param key 插入的节点值
     * @return 新的二叉树
     */
    public TreeNode inster(int key){
        //新增的节点
        TreeNode newNode=new TreeNode(key);
        //根节点
        TreeNode current=root;
        //父节点
        TreeNode parent=null;
        //如果根节点是空的,那么新增的节点就是当根节点
        if (current==null) {
            root=newNode;
            return newNode;
        }
        //如果根节点不为空
        //循环
        while (true) {
            parent=current;
            if (key<current.value) {//如果当前节点值大于插入值,找左节点
                current=current.left;
                if (current==null) {
                    parent.left=newNode;
                    return newNode;
                }
            } else {//如果当前节点值小于插入值,找右节点
                current=current.right;
                if (current==null) {
                    parent.right=newNode;
                    return newNode;
                }
            }
        }
    }
    /**
     * Title: 查找节点</br>
     * 其算法复杂度 : O(lgN),树深(N)
     * 步骤:
     *  1. 从root节点开始
     *  2. 比当前节点值小,则找其左节点
     *  3. 比当前节点值大,则找其右节点
     *  4. 与当前节点值相等,查找到返回TRUE
     *  5. 查找完毕未找到
     * Description: TestDemo</br>
     * @author xg.c
     * @date 2016年7月26日 上午11:00:34
     * @param key 查找的节点
     * @return 返回查找值
     */
    public TreeNode search(int key){
        //根节点
        TreeNode current=root;
        //循环
        while(current!=null && key!=current.value){
            if (key<current.value) {//比当前节点值小,则找其左节点
                current=current.left;
            } else {//比当前节点值大,则找其右节点
                current=current.right;
            }
        }
        return current;
    }
    /**
     * Title: 删除节点
     * 步骤:
     *  1.找到删除节点
     *  2.如果删除节点左节点为空 , 右节点也为空;
     *  3.如果删除节点只有一个子节点 右节点 或者 左节点
     *  4.如果删除节点左右子节点都不为空
     * @author: xg.chen
     * @param key 删除的节点
     * @return
     */
    public TreeNode delete (int key) {
        TreeNode parent  = root;
        TreeNode current = root;
        boolean isLeftChild = false;
        // 找到删除节点 及 是否在左子树
        while (current.value != key) {
            parent = current;
            if (current.value > key) {
                isLeftChild = true;
                current = current.left;
            } else {
                isLeftChild = false;
                current = current.right;
            }

            if (current == null) {
                return current;
            }
        }

        // 如果删除节点左节点为空 , 右节点也为空
        if (current.left == null && current.right == null) {
            if (current == root) {
                root = null;
            }
            // 在左子树
            if (isLeftChild == true) {
                parent.left = null;
            } else {
                parent.right = null;
            }
        }
        // 如果删除节点只有一个子节点 右节点 或者 左节点
        else if (current.right == null) {
            if (current == root) {
                root = current.left;
            } else if (isLeftChild) {
                parent.left = current.left;
            } else {
                parent.right = current.left;
            }

        }
        else if (current.left == null) {
            if (current == root) {
                root = current.right;
            } else if (isLeftChild) {
                parent.left = current.right;
            } else {
                parent.right = current.right;
            }
        }
        // 如果删除节点左右子节点都不为空
        else if (current.left != null && current.right != null) {
            // 找到删除节点的后继者
            TreeNode successor = getDeleteSuccessor(current);
            if (current == root) {
                root = successor;
            } else if (isLeftChild) {
                parent.left = successor;
            } else {
                parent.right = successor;
            }
            successor.left = current.left;
        }
        return current;
    }

    /**
     * Title: 获取删除节点的后继者,删除节点的后继者是在其右节点树种最小的节点
     * @author: xg.chen
     * @param deleteNode 删除的节点
     * @return
     */
    public TreeNode getDeleteSuccessor(TreeNode deleteNode) {
        // 后继者
        TreeNode successor = null;
        TreeNode successorParent = null;
        TreeNode current = deleteNode.right;

        while (current != null) {
            successorParent = successor;
            successor = current;
            current = current.left;
        }

        // 检查后继者(不可能有左节点树)是否有右节点树
        // 如果它有右节点树,则替换后继者位置,加到后继者父亲节点的左节点.
        if (successor != deleteNode.right) {
            successorParent.left = successor.right;
            successor.right = deleteNode.right;
        }

        return successor;
    }
}

2、节点的数据接口

package com.cxg.demo.test.tree;
/**
 * Title: 节点的数据接口,节点分左节点和右节点及本身节点值</br>
 * Description: TestDemo</br>
 * @author xg.c
 * @date 2016年7月26日 上午10:15:46
 */
public class TreeNode {
    //节点的值
    int value;
    //左节点
    TreeNode left;
    //右节点
    TreeNode right;
    //节点的构造方法
    public TreeNode(int value) {
        this.value = value;
        left  = null;
        right = null;
    }
}

3、测试单元

package com.cxg.demo.test.tree;

/**
 * Title: BST算法测试</br>
 * Description: TestDemo</br>
 * @author xg.c
 * @date 2016年7月26日 上午10:44:46
 */
public class TestBST {
    public static void main(String[] args) {
        BinarySearchTree bst=new BinarySearchTree();
        //插入节点并打印数组
        bst.inster(3);
        bst.inster(5);
        bst.inster(2);
        bst.inster(6);
        bst.inster(4);
        bst.inster(8);
        bst.inster(20);
        bst.inster(21);
        bst.inster(33);
        bst.toString(bst.root);
        System.out.println();
        //查询是否存在此节点
        TreeNode node=bst.search(8);
        System.out.println("是否存在节点值为8 => " + node.value);
        //删除节点
        TreeNode node1=bst.delete(8);
        System.out.println("删除后的树型节点为:"+node1.value);
        bst.toString(bst.root);
        System.out.println();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值