二叉搜索树

  • 二叉搜索树要么是一颗空树,要么是满足以下条件的二叉树:对于二叉搜索树上每个节点X,左子树所有项的值小于X的值,右子树所有项的值大于X的值。
  • 中序遍历二叉搜索树可以得到其升序排序结果。
  • 以下代码提供了二叉搜索树创建、插入以及中序遍历的功能:
public class BinarySearchTree<T extends  Comparable> {
    private Node root;

    public BinarySearchTree() {}
    public BinarySearchTree(T[] array) {
        for(T num : array) {
            insert(new Node(num));
        }
    }

    public Node getRoot() {
        return root;
    }

    public void setRoot(Node root) {
        this.root = root;
    }

    public void insert(Node node) {

        if(root==null) {
            root = node;
        } else {

            Node current = root;
            Node parent = null;

            while(true) {
                parent = current;
                if(node.getData().compareTo(current.getData())<0) {  //往左
                    current = current.getLeft();
                    if(current==null) {
                        parent.setLeft(node);
                        break;
                    }
                } else {  //往右
                    current = current.getRight();
                    if(current==null) {
                        parent.setRight(node);
                        break;
                    }
                }
            }
        }

    }

    //中序遍历
    public void inOrderTraverse(Node root) {
        if(root==null) {
            return;
        } else {
            inOrderTraverse(root.getLeft());
            System.out.print(root.getData()+"\t");
            inOrderTraverse(root.getRight());
        }
    }
}
  • 由于删除稍微有点麻烦,这里单独实现。思路如下:
  1. 如果是叶子节点,直接设为null即可(在代码里需要设置相应的父节点信息,否则父节点指向的位置没变,信息没有被真正删除);
  2. 如果仅有左孩子或右孩子,则直接用左孩子或右孩子替代该节点即可;
  3. 如果同时有左孩子和右孩子,根据中序遍历的性质,将右子树中最左侧节点替代该节点最佳(其实也可以找到左子树中最右侧的节点),然后递归删除那个最小节点。

具体实现代码如下:

public void remove(Node node) {
        //首先要找到这个节点,并保存该节点的父节点信息
        Node current = root;
        Node parent = null;
        while(true) {
            parent = current;
            if(node.getData().compareTo(current.getData())<0) { //在左子树中
                current = current.getLeft();
                if(current.getData().compareTo(node.getData())==0) { //找到该节点
                    break;
                }
            } else if(node.getData().compareTo(current.getData())==0){ //就是当前节点
                break;
            } else { //在右子树中
                current = current.getRight();
                if(current.getData().compareTo(node.getData())==0) { //找到该节点
                    break;
                }
            }
        }

        if(current.getLeft()==null&&current.getRight()==null) { //叶子节点
            if(current.getData().compareTo(parent.getLeft().getData())==0) {
                parent.setLeft(null);
            } else {
                parent.setRight(null);
            }
        } else if(current.getLeft()!=null&&current.getRight()==null) { //仅有左孩子
            if(current.getData().compareTo(parent.getLeft().getData())==0) {
                parent.setLeft(current.getLeft());
            } else {
                parent.setRight(current.getLeft());
            }
        } else if(current.getLeft()==null&&current.getRight()!=null) { //仅有右孩子
            if(current.getData().compareTo(parent.getLeft().getData())==0) {
                parent.setLeft(current.getRight());
            } else {
                parent.setRight(current.getRight());
            }
        } else { //左右孩子都有
            Node tmp = current.getRight();
            parent = current;
            while(tmp.getLeft()!=null) {
                parent = tmp;
                tmp = tmp.getLeft();
            }
            T min = (T)tmp.getData();
            if(tmp.getData().compareTo(parent.getLeft().getData())==0) {
                parent.setLeft(null);
            } else {
                parent.setRight(null);
            }
            current.setData(min);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值