二叉搜索树

一、定义

左子树的节点值均小于根节点
右子树的值均大于根节点

二、基本操作

1 创建节点类

package tree;

public class Node {
    private int data;
    private Node leftChild;
    private Node rightChild;

    public Node() {}

    public Node(int data) {
        this.data = data;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Node getLeftChild() {
        return leftChild;
    }

    public void setLeftChild(Node leftChild) {
        this.leftChild = leftChild;
    }

    public Node getRightChild() {
        return rightChild;
    }

    public void setRightChild(Node rightChild) {
        this.rightChild = rightChild;
    }

    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                ", leftChild=" + leftChild +
                ", rightChild=" + rightChild +
                '}';
    }
}

2 二叉树的查找操作

  • 从根节点开始查找
    * 只要当前节点不为空如果要查找的数据大于当前节点,当前节点等于当前节点的右孩子;
    * 如果要查找的数据等于当前节点,返回当前节点
    * 如果要查找的数据小于当前节点,当前节点等于当前节点的左孩子

三、完整代码

package tree;

/**
 * 二叉树基本的类结构
 */
public class BinaryTree {
    private Node root;

    public BinaryTree() {
        root = null;
    }

    //查找某个节点
    public Node find(int data) {
        Node current = root;
        while (current != null) { //当前节点不是null的时候,才继续循环
            if (data < current.getData()) {
                current = current.getLeftChild();
            } else if (data > current.getData()) {
                current = current.getRightChild();
            } else {
                return current;
            }
        }
        //循环完了,current==null说明树里根本没有我们要找的节点
        return null;
    }

    //插入节点
    public boolean insert(int data) {
        Node newNode = new Node(data);
        if (root == null) {
            root = newNode;
            return true;
        } else {
            Node current = root;
            Node parentNode = null;
            while (current != null) {
                parentNode = current;
                if (data < current.getData()) {
                    current = current.getLeftChild();
                    if (current == null) {
                        parentNode.setLeftChild(newNode);
                        return true;
                    }
                } else {
                    current = current.getRightChild();
                    if (current == null) {
                        parentNode.setRightChild(newNode);
                        return true;
                    }
                }
            }
        }
        return false;  //插入失败
    }

    //遍历节点
    //中序遍历
    public void midOrder(Node current) {
        //先左
        if (current == null) {
            return;
        } else {
            midOrder(current.getLeftChild());
            System.out.println(current.getData());
            midOrder(current.getRightChild());
        }
    }

    //前序遍历
    public void preOrder(Node current) {
        if (current == null) {
            return;
        } else {
            System.out.println(current.getData());
            preOrder(current.getLeftChild());
            preOrder(current.getRightChild());
        }
    }

    //后序遍历
    public void afterOrder(Node current) {
        if (current == null) {
            return;
        } else {
            afterOrder(current.getLeftChild());
            afterOrder(current.getRightChild());
            System.out.println(current.getData());
        }
    }

    //查找最大值和最小值
    public Node getMaxNode() {
        Node current = root;
        Node maxNode = current;
        while (current != null) {
            maxNode = current;
            current = current.getRightChild();
        }
        return maxNode;
    }

    public Node getMinNode() {
        Node current = root;
        Node minNode = current;
        while (current != null) {
            minNode = current;
            current = current.getLeftChild();
        }
        return minNode;
    }

    //删除节点
    public boolean delete(int data) {
        //找到要删除的节点
        Node current = root;
        Node parent = null;
        boolean isLeftChild = false;  //判断当前节点是其父节点的左孩子还是右孩子
        while (current.getData() != data) {
            parent = current;
            if (data < current.getData()) {
                current = current.getLeftChild();
                isLeftChild = true;
            } else {
                current = current.getRightChild();
                isLeftChild = false;
            }
            if (current == null) {  //树里根本没有要删除的节点
                return false;  //结束方法,循环结束
            }
        }
        //正常循环结束,找到了要删除的节点

        //删除找到的节点
        if (current.getLeftChild() == null && current.getRightChild() == null) { //要删除节点是叶子节点
            if (current == root) {
                root = null;
            } else {
                if (isLeftChild) {  //当前节点是父节点的左孩子
                    parent.setLeftChild(null);
                } else {
                    parent.setRightChild(null);
                }
            }
            return true;
        } else if (current.getLeftChild() != null && current.getRightChild() == null) {
            if (current == root) {
                root = current.getLeftChild();
            } else {
                if (isLeftChild) {
                    parent.setLeftChild(current.getLeftChild());
                } else {
                    parent.setRightChild(current.getLeftChild());
                }
            }
            return true;
        } else if (current.getLeftChild() == null && current.getRightChild() != null) {
            if (current == root) {
                root = current.getRightChild();
            } else {
                if (isLeftChild) {
                    parent.setLeftChild(current.getRightChild());
                } else {
                    parent.setRightChild(current.getRightChild());
                }
            }
            return true;
        } else { //要删除的节点有两个子节点的情况
            //先找到要被删除的节点的右子树中的最小节点
            Node replaceNode = getReplaceNode(current);

            if (current == root) {
                root = replaceNode;
            } else {
                if (isLeftChild) {
                    parent.setLeftChild(replaceNode);
                } else {
                    parent.setRightChild(replaceNode);
                }
            }
            replaceNode.setLeftChild(current.getLeftChild());
            return true;
        }
    }

    public Node getReplaceNode(Node delNode) {
        Node replaceNode = delNode;
        Node replaceNodeParent = delNode;
        Node grnCurrent = delNode.getRightChild();

        while (grnCurrent != null) {
            replaceNodeParent = replaceNode;
            replaceNode = grnCurrent;
            grnCurrent = grnCurrent.getLeftChild();
        }

        if (replaceNode != delNode.getRightChild()) {
            replaceNodeParent.setLeftChild(replaceNode.getRightChild());
            replaceNode.setRightChild(delNode.getRightChild());
        }
        return replaceNode;   //我们要找的右子树中的最小节点
    }
}

四、测试

package tree;

public class BinaryTreeTest {
    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.insert(40);
        bt.insert(36);
        bt.insert(37);
        bt.insert(85);
        bt.insert(49);
        bt.insert(88);

        Node root = bt.find(40);

        bt.midOrder(root);

        System.out.println();

        bt.delete(85);

        bt.midOrder(root);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值