二叉查找树Java实现

二叉查找树

首先是一棵二叉树,使其称为查找树的关键性质是其某节点的左子树中任意值都小于该节点,右子树中任意值都大于该节点。

代码如下:

public class BinaryTree<T extends Comparable<T>> {

    private TreeNode<T> root = null;
    private LinkedList<TreeNode<T>> trace = new LinkedList<>();// 用于非递归实现删除时存储访问路径

    BinaryTree(TreeNode<T> root) {
        this.root = root;
    }

    public void clear() {
        root = null;
    }

    public boolean isEmpty() {
        return root == null;
    }

    public boolean contains(T element) {
        return contains0(root, element);
    }

    public void insert(T element) {
        TreeNode<T> node = new TreeNode<T>(element);
        insert0(root, node);
    }

    /**
     * 
     * @Title: insert0
     * 
     * @Description: 递归插入
     * 
     * @param root
     * @param node
     * 
     * @return: void
     * 
     */
    private void insert0(TreeNode<T> root, TreeNode<T> node) {
        if (root.element.compareTo(node.element) < 0) {
            if (root.right == null) {
                root.right = node;
                return;
            } else {
                insert0(root.right, node);
            }
        }
        if (root.element.compareTo(node.element) > 0) {
            if (root.left == null) {
                root.left = node;
                return;
            } else {
                insert0(root.left, node);
            }
        }
    }

    // 删除一个子树的某个节点,返回新的子树根节点,给适当的父亲(左或者右),递归删除
    /**
     * 
     * @Title: remove
     * 
     * @Description: 递归删除
     * 
     * @param node
     * @param element
     * @return
     * 
     * @return: TreeNode<T>
     * 
     */
    public TreeNode<T> remove(TreeNode<T> node, T element) {
        if (node == null) {
            return node;
        }

        int compare = node.element.compareTo(element);
        // 寻找将要删除的节点
        if (compare > 0) {
            // 在节点左边 则去左边子树删除,并返回新的子树
            node.left = remove(node.left, element);
        } else if (compare < 0) {

            node.right = remove(node.right, element);
            // 找到了将要删除的节点
        } else if (node.left != null && node.right != null) {
            // 如果该节点有两个儿子,找到该节点右子树中的最小节点值赋值给当前节点
            TreeNode<T> min = findMin(node.right);
            node.element = min.element;
            // 再去右子树中删除该最小节点,并返回新的右子树给之前的节点
            node.right = remove(node.right, min.element);
        } else {
            // 如果该节点有左儿子则返回左儿子,有右儿子则返回右儿子(即该节点的儿子充当了新的子树),如果都没有则该叶子节点已经被删除
            node = node.left == null ? node.right : node.left;
        }
        return node;
    }

    /**
     * 
     * @Title: delete
     * 
     * @Description: 非递归删除,利用了栈来存储路径信息
     * 
     * @param element
     * @return
     * 
     * @return: boolean
     * 
     */
    public boolean delete(T element) {
        trace = findTrace(root, element);
        if (trace == null) {
            return false;
        }
        // 找到将要被删除的节点
        TreeNode<T> node = trace.pop();
        // 被删除节点没有儿子或者只有一个儿子
        if (node.left == null || node.right == null) {
            return delete0(root, element);
        }

        // 被删除节点有两个儿子
        // 找到节点右儿子中的最小值
        TreeNode<T> rightMin = findMin(node.right);
        // 直接删除该最小值节点
        if (delete0(root, rightMin.element)) {
            // 将最小右儿子的值赋给将要被删除的节点
            node.element = rightMin.element;
            return true;
        }
        return false;
    }

    private boolean delete0(TreeNode<T> nodeParent, T element) {
        trace.clear();
        trace = findTrace(nodeParent, element);
        if (trace == null) {
            return false;
        }
        TreeNode<T> node = trace.pop();
        // 被删除节点是叶子节点
        if (node.left == null && node.right == null) {
            TreeNode<T> parent = trace.peek();
            if (parent.left != null && parent.left.equals(node)) {
                parent.left = null;
                return true;
            }
            parent.right = null;
            return true;
        }
        // 被删除节点仅有一个右儿子
        if (node.left == null) {
            TreeNode<T> parent = trace.peek();
            if (parent.left != null && parent.left.equals(node)) {
                parent.left = node.right;
                node.right = null;
                return true;
            }
            parent.right = node.right;
            node.right = null;
            return true;
        }
        // 被删除节点仅有一个左儿子
        if (node.right == null) {
            TreeNode<T> parent = trace.peek();
            if (parent.left != null && parent.left.equals(node)) {
                parent.left = node.left;
                node.left = null;
                return true;
            }
            parent.right = node.left;
            node.left = null;
            return true;
        }

        return false;
    }

    public TreeNode<T> find(TreeNode<T> node, T element) {
        LinkedList<TreeNode<T>> trace = findTrace(node, element);
        return trace == null ? null : trace.pop();
    }

    private LinkedList<TreeNode<T>> findTrace(TreeNode<T> node, T element) {
        trace.push(node);
        if (node.element.equals(element)) {
            return trace;
        }
        if (node.right != null && node.element.compareTo(element) < 0) {
            return findTrace(node.right, element);
        }
        if (node.left != null && node.element.compareTo(element) > 0) {
            return findTrace(node.left, element);
        }
        return null;
    }

    public TreeNode<T> findMin(TreeNode<T> node) {
        if (node.left == null) {
            return node;
        }
        return findMin(node.left);
    }

    public void traverseInPostOrder(TreeNode<T> node) {
        if (node.left != null) {
            traverseInPostOrder(node.left);
        }
        if (node.right != null) {
            traverseInPostOrder(node.right);
        }
        System.out.print(node.element + " ");
    }

    public void traverseInPreOrder(TreeNode<T> node) {

        System.out.print(node.element + " ");

        if (node.left != null) {
            traverseInPreOrder(node.left);
        } else {
            System.out.print("# ");
        }

        if (node.right != null) {
            traverseInPreOrder(node.right);
        } else {
            System.out.print("# ");
        }
    }

    private boolean contains0(TreeNode<T> root, T element) {
        System.out.println(root.element.equals(element));
        if (root.element.equals(element)) {
            return true;
        }
        if (root.element.compareTo(element) < 0 && root.right != null) {
            return contains0(root.right, element);
        } else if (root.left != null) {
            return contains0(root.left, element);
        }
        return false;
    }

    private static class TreeNode<T> {
        T element;
        TreeNode<T> left;
        TreeNode<T> right;

        TreeNode(T element) {
            this.element = element;
        }

        public String toString() {
            return element.toString();
        }
    }
好的,下面是一份基本的二叉查找树Java 实现代码: ``` public class BinarySearchTree { private Node root; private class Node { private int key; private Node left; private Node right; public Node(int key) { this.key = key; this.left = null; this.right = null; } } public BinarySearchTree() { root = null; } public void insert(int key) { root = insert(root, key); } private Node insert(Node node, int key) { if (node == null) { node = new Node(key); return node; } if (key < node.key) { node.left = insert(node.left, key); } else if (key > node.key) { node.right = insert(node.right, key); } return node; } public void delete(int key) { root = delete(root, key); } private Node delete(Node node, int key) { if (node == null) { return null; } if (key < node.key) { node.left = delete(node.left, key); } else if (key > node.key) { node.right = delete(node.right, key); } else { if (node.left == null) { return node.right; } else if (node.right == null) { return node.left; } node.key = findMin(node.right).key; node.right = delete(node.right, node.key); } return node; } private Node findMin(Node node) { while (node.left != null) { node = node.left; } return node; } public boolean search(int key) { return search(root, key); } private boolean search(Node node, int key) { if (node == null) { return false; } if (key == node.key) { return true; } else if (key < node.key) { return search(node.left, key); } else { return search(node.right, key); } } public void inorderTraversal() { inorderTraversal(root); } private void inorderTraversal(Node node) { if (node != null) { inorderTraversal(node.left); System.out.print(node.key + " "); inorderTraversal(node.right); } } } ``` 这份代码实现二叉查找树的基本操作,包括插入、删除、搜索和中序遍历。你可以根据自己的需求进行修改和拓展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值