Java~实现二叉搜索树(二叉排序树)的查找、增加、删除

package Test;

import javax.xml.soap.Node;

/**
 * 概念:二叉搜索树又称为二叉排序树,它或是一棵空树,或是具有以下性质的二叉树:
 * 1、若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
 * 2、若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
 * 3、它的左右子树也分别是二叉搜索树
 */
public class TwoTreeNode {
    /**
     * 查找:根据二叉树的性质,让find指向根节点,进行循环判断,要找到key如果比find的key小,则在find左子树查找,如果大则在find右子树茶轴
     */
    public Node search(int key) {
        Node find = this.root;
        while (find != null) {
            if (key < find.key) {
                find = find.left;
            } else if (key > find.key) {
                find = find.right;
            } else {
                return find; // 找到对应的节点
            }
        }
        return null;
    }

    /**
     * 增加:为新加的节点找到合适的位置
     * 1、在找到合适位置的时候发现此二叉搜索树已有待插入节点的可以,此时需要将旧的value进行覆盖
     * 2、找到要插入节点的父节点,此时需要判断如果待插入的key比父节点key大,则插入父节点right,反之插入到父节点left
     */
    public boolean insert(int key, int value) {
        if (this.root == null) {
            // 此时是空树
            this.root = new Node(key, value);
            return true;
        }
        Node find = this.root;
        Node prev = null;
        while (find != null) {
            if (key < find.key) {
                prev = find;
                find = find.left; // key比父节点小,在父节点的left
            } else if (key > find.key) {
                prev = find;
                find = find.right; // key比父节点大,在父节点的right
            } else {
                find.value = value; // key等于父节点,使用value覆盖
                return true;
            }
        }
        // 结束循环,说明此时要找到插入该节点的父节点
        Node newNode = new Node(key, value);
        if (key < prev.key) {
            prev.left = newNode;
        } else {
            prev.right = newNode;
        }
        return true;
    }

    /**
     * 删除:假设 cur 是待删除的节点,parent 是待删除节点的父节点
     * 1、找到待删除节点和待删除节点的父节点
     * 2、进行分类讨论删除操作。三大类:① 待删除节点的左子树为空,② 待删除节点右子树为空,③ 待删除节点左右子树都不为空
     */
    public void delete(int key) {
        if (this.root == null) {
            return;
        }
        Node find = this.root;
        Node parent = null;
        while (find != null) {
            if (key < find.key) {
                parent = find;
                find = find.left;
            } else if (key > find.key) {
                parent = find;
                find = find.right;
            } else {
                // 找到要删除的节点
                // 分三大类,find左子树为空,右子树为空,左右子树都不为空
                if (find.left == null) {
                    // 待删除的节点左子树为空,分三种,① 是根节点。② 是parent的左节点。③ 是parent的右节点
                    if (find == this.root) {
                        this.root = find.right;
                        return;
                    } else if (find == parent.left) {
                        parent.left = find.right;
                        return;
                    } else if (find == parent.right) {
                        parent.right = find.right;
                        return;
                    }
                } else if (find.right == null) {
                    // 待删除节点的右子树为空,分三种① 是跟节点,② 是parent的左节点,③ 是parent的右节点
                    if (find == this.root) {
                        this.root = find.left;
                        return;
                    } else if (find == parent.left) {
                        parent.left = find.left;
                        return;
                    } else if (find == parent.right) {
                        parent.right = find.left;
                        return;
                    }
                } else {
                    // 待删除节点左右子树都不为空,找到左子树的最小节点,与待删除的节点进行赋值,然后删除最小节点
                    Node goatParent = find;
                    Node goat = find.right;
                    while (goat.left != null) {
                        goatParent = goat;
                        goat = goat.left;
                    }
                    // 进行赋值
                    find.key = goat.key;
                    find.value = goat.value;
                    // 删除这个最小节点,分两种,① goat是goatParent的左节点;② goat是goatParent的右节点;
                    if (goat == goatParent.left) {
                        goatParent.left = goat.right;
                        return;
                    } else {
                        //如果goat是goatParent的右节点,那么goatParent一定还指向find结点,而且此时goat的左结点还是为空
                        goatParent.right = goat.right;
                        return;
                    }
                }
            }
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值