二叉树自定义

java学习笔记 二叉树

//BsTreeNode的定义
public class BsTreeNode<T extends Comparable> {
//关键字(键值)
T nodeKey;
//左节点引用
BsTreeNode left;
//右节点引用
BsTreeNode right;
//父节点引用,删除操作会用到
BsTreeNode parent;
//构造方法 结点的值
public BsTreeNode() {
}

public BsTreeNode(T value) {
    this.nodeKey = value;
}

public T getNodeKey() {
    return nodeKey;
}

@Override
public String toString() {
    return nodeKey.toString();
}

public BsTreeNode<T> getLeft() {
    return left;
}

public void setLeft(BsTreeNode<T> left) {
    this.left = left;
}

public BsTreeNode<T> getRight() {
    return right;
}

public void setRight(BsTreeNode<T> right) {
    this.right = right;
}
/*
* 中序遍历BsTree,打印节点值(递归实现)
* */
public void inOrder(BsTreeNode<T> root){
    if(root == null){
        return;
    }
    inOrder(root.left);
    System.out.println("->"+root.toString());
    inOrder(root.right);
}

/*
    使用递归实现BsTree查找
    @param root BST根节点引用
    @param key 待查找的节点值
    @return 命中的节点
     */
public BsTreeNode<T> searchRecursively(BsTreeNode<T> root, T key){
    if(root == null){
        return  null; //空指针处理
    }
    if(root.getNodeKey().compareTo(key)>0){
        //当前节点值比搜索值大,左子树查找
        return searchRecursively(root.getLeft(),key);
    }else if(root.getNodeKey().compareTo(key)<0){  //这几个if把原文的NodeKey替换了。原本是Value
        //当前节点值比搜索值小,右子树查找
        return searchRecursively(root.getRight(),key);
    }else {return  root;}  //查找命中
}
/*
    使用递归实现BsTree插入
    @param root BST根节点引用
    @param key 待插入的节点值
    @return 插入成功返回true,如果树中有该元素不需要插入则返回false
     */
    public boolean insertRecursively(BsTreeNode<T> root, T key){
        if(root.nodeKey.compareTo(key)>0){
            if(root.left == null){
                BsTreeNode<T> node = new BsTreeNode<>(key);//将key赋值给新节点
                root.left = node;
                node.parent = root;
                return true;
            }else{
                return insertRecursively(root.left,key);
            }
        }else if (root.nodeKey.compareTo(key)<0){
            if(root.right == null){
                BsTreeNode<T> node = new BsTreeNode<>(key);//将key赋值给新节点
                root.right = node;
                node.parent = root;
                return true;
            }else{
                return insertRecursively(root.right,key);
            }
        }else {
            return false; //该节点被遍历到了,已存在,无法插入
        }
    }
    //插入位置一定是叶子位置,不会导致树结构调整,插入操作极为简单
/**
 * 利用二分查找实现BsTree插入过程
 */

public boolean insertRecursively(BsTreeNode<T> root, BsTreeNode<T> nodeInserted){
    if(root == null){
        root = nodeInserted;
        return true;
    } if(root.nodeKey.compareTo(nodeInserted.nodeKey)>0){ //在左子树找插入位置(叶子节点位置),构造一个新的节点
                                                              // 作为叶子节点插入 BST
        if(root.left == null){
            root.left = nodeInserted;
            nodeInserted.parent = root;                        //设置新节点parent
            return true;
        }else{
            return insertRecursively(root.left, nodeInserted);
        }
    }else if(root.nodeKey.compareTo(nodeInserted.nodeKey)<0){ //在右子树找插入位置(叶子节点位置),构造一个新的节点
        // 作为叶子节点插入 BST
        if(root.right == null){
            root.right = nodeInserted;
            nodeInserted.parent = root;                        //设置新节点parent
            return true;
        }else{
            return insertRecursively(root.right, nodeInserted);
        }
    }else {
        return false;
    }
}
/*删除操作,四种情形
1.	叶子节点
2.	只有左子树节点
3.	只有右子树的节点
4.	左右子树都有的节点
* */

public void deleteRecursively(BsTreeNode currentNode, T key){
if(currentNode ==null){
System.out.println(“不存在该节点”);
return;
}
//查找
//当前节点键值大于key,去左子树查找
if(currentNode.nodeKey.compareTo(key)>0){
deleteRecursively(currentNode.left,key); //递归
}
//当前节点键值小于key,去右子树查找
if(currentNode.nodeKey.compareTo(key)<0){
deleteRecursively(currentNode.right,key); //递归
}
//当前节点键值 = key,开始进行删除操作
else {
//1.对于第一种情形,左右子树均为空,直接删掉,不影响树结构调整
if (currentNode.right == null && currentNode.left == null) {
//通过父节点删除节点
BsTreeNode parent = currentNode.parent; //这里的第一个parent 局部变量,不影响
if (parent.left == currentNode) {
parent.left = null;
}
if (parent.right == currentNode) {
parent.right = null;
}
return;
}
else if (currentNode.right ==null){
//2.第二种情形,将左子树替换被删除节点
BsTreeNode rootLeft = currentNode.left;
T temp = rootLeft.nodeKey;
currentNode.left = rootLeft.left; //令被删除节点的左节点变为下一个节点的左节点,上移
currentNode.right = rootLeft.right;
currentNode.nodeKey = temp;//改变键值
//修正parent 现在rootleft.left/right 的父节点还不是currentNode,是rootleft = currentNode.left
if(currentNode.left!=null){
rootLeft.left.parent = currentNode;
}
if(currentNode.right!=null){
rootLeft.right.parent = currentNode;
}
}else if(currentNode.left ==null){
//3.第3种情形,将右子树替换被删除节点
BsTreeNode rootRight = currentNode.right; //一个右节点
T temp = rootRight.nodeKey;//右节点的键值
currentNode.left = rootRight.left;//挪动树
currentNode.right = rootRight.right;
currentNode.nodeKey = temp; //改变键值
//修正parent,将rootRight的左右子节点指向传递进来的参数currentNode
if(currentNode.left!=null){
rootRight.left.parent = currentNode;
}
if(currentNode.right!=null){
rootRight.right.parent = currentNode;
}
}else{
// 第四种 找到当前节点的中序前驱节点(或直接后继)代替待删除节点,同时在
// 二叉排序树中对其做删除操作

        //当前节点的中序前驱节点
        BsTreeNode<T> node = currentNode.left;
        while(node.right!=null){
            node = node.right; //找直接前驱
        }
        //节点内容替换
        currentNode.nodeKey = node.nodeKey;
        //删除前驱节点
        deleteRecursively(node,node.nodeKey);

    }
}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值