Java实现二叉搜索树

Java实现二叉搜索树

目录

Java实现二叉搜索树


package com.company.struct;


//二插搜索树 值不能为null
//如果为自定义类型,则需要规定排序规则  二插搜索树没有索引的概念
//内置的类型都默认实现了compareable
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;

@SuppressWarnings("all")
public class BinarySearchTree<E /*extends Comparable*/>{  //必须实现排序接口,写在比较函数中

    private int size;
    public Node<E> root;
    private java.util.Comparator<E> comparator;
    public BinarySearchTree(java.util.Comparator<E> comparator) {
        this.comparator = comparator;
    }

    public BinarySearchTree() {
        this(null);
    }


    public static class Node<E> {
        E element;
        Node<E> left; //左节点
        Node<E> right; //右节点
        Node<E> parent; //父节点

        public Node(E element,Node<E> parent) {  //一定有父节点,但是左右节点不一定有
            this.element = element;
            this.parent = parent;
        }

        public boolean isLeaf()
        {
            return (left == null && right == null);
        }

        public boolean hasTwoChild()
        {
            return  left != null && right != null;
        }

        public boolean isLeftChild()
        {
            return parent!=null && this == parent.left;
        }

        public boolean isRightChild()
        {
            return parent!=null && this == parent.right;
        }

    }

    private void elementNotNullCheck(E element)
    {
        if (element == null)
        {
            throw new IllegalArgumentException("element must not be null !");
        }
    }

    public void levelOrder(visitor<E> visitor)
    {
        if (root == null) return;
        Queue<Node<E>> queue = new LinkedList<Node<E>>();
        queue.offer(root);
        while (!queue.isEmpty())
        {
            Node<E> node1 = queue.poll();
            visitor.visit(node1.element);  //修改操作
            if (node1.left != null) {
                queue.offer(node1.left);
            }
            if (node1.right != null) {
                queue.offer(node1.right);
            }
        }

    }

    public static interface visitor<E>
    {
        void visit(E element);  //要完成什么操作,遍历或者修改
    }

    public int size()
    {
        return this.size;
    }

    public boolean isEmpty()
    {
        return size == 0;
    }

    public void clear()
    {
        root = null;
        size = 0;
    }
    public void add(E element)
    {
        elementNotNullCheck(element);
        if (root == null) //添加第一个元素
        {
            root = creatNode(element,null);
            size++;
            afterAdd(root);
            return;
        }
        else {  //添加的不是第一个节点
            Node<E> tmp = this.root;
            Node<E> parentNode = this.root;
            int compare = 0;
            while (tmp != null) {
                compare = compare(element, tmp.element);
                parentNode = tmp;
                if (compare > 0) {  // >
                    tmp = tmp.right;
                } else if (compare < 0) {  //<
                    tmp = tmp.left;
                } else {  // =
                    tmp.element = element;
                }
            }
            Node<E> node = creatNode(element,parentNode);
            if (compare>0) {
                parentNode.right = node;
                this.size++;

            } else {
                parentNode.left = node;
                this.size++;
            }
            //新添加节点之后的处理
            afterAdd(node);
        }
    }

    //旋转二叉树使平衡
    protected void afterAdd(Node<E> node)
    {
    }

    protected Node<E> creatNode(E element,Node<E> parent)
    {
        return new Node<E>(element, parent);
    }

    //返回值为0,说明e1=e2
    // >0 e1>e2
    // <0 e1<e2
    private int compare(E e1, E e2)
    {
        if (comparator != null) {
            return this.comparator.compare(e1, e2);
        }
        else {
            return ((java.lang.Comparable<E>)e1).compareTo(e2);
        }
    }

    private void remove(Node<E> node)
    {
        if (node == null) return;
        size--;
        if (node.hasTwoChild())   //删除度为2的节点
        {
            //找到前继节点
            Node<E> successor = successor(node);
            //用前继节点的值覆盖度为2的节点的值
            node.element = successor.element;
            //删除后继节点
            node = successor;
        }
        //删除node节点,度必为0或1
        Node<E> replaceNode = node.left != null ? node.left : node.right;
        if (replaceNode != null)  //node是度为1的节点
        {
            replaceNode.parent = node.parent;
            if (node.parent == null) { //根节点
                root = replaceNode;
            }else if (node == node.parent.right)
            {
                node.parent.right = replaceNode;
            }else if(node == node.parent.left) {
                node.parent.left = replaceNode;
            }
        }else if (node.parent == null) {//根节点
                root= null;
        }else {  //叶子节点但不是根节点
            if (node == node.parent.right) {
                node.parent.right = null;
            }else {
                node.parent.left = null;
            }
        }
    }

    private Node<E> node(E element)
    {
        Node<E> tmp = root;
        while (tmp!=null)
        {
            int cmp = compare(element,tmp.element);
            if (cmp == 0) {
                return tmp;
            }if (cmp>0)
            {
                tmp = tmp.right;
            }else{
                tmp = tmp.left;
            }
        }
        return null;
    }

    public  void remove(E element)
    {
        remove(node(element));
    }

     public boolean contains(E element)
    {
        return node(element)!=null;
    }

    //前序遍历
    public void preOrederTraversal(Node<E> node)
    {
        if (node == null) return;
        System.out.print(node.element+" ");
        preOrederTraversal(node.left);
        preOrederTraversal(node.right);
    }
    public void preOrederTraversal()
    {
        preOrederTraversal(root);
    }

    //中序遍历
    public void inOrederTraversal(Node<E> node)
    {
        if (node == null) return;
        inOrederTraversal(node.left);
        System.out.print(node.element+" ");
        inOrederTraversal(node.right);
    }
    public void inOrederTraversal()
    {
        inOrederTraversal(root);
    }

    //后序遍历
    public void postOrederTraversal(Node<E> node)
    {
        if (node == null) return;
        postOrederTraversal(node.left);
        postOrederTraversal(node.right);
        System.out.print(node.element+" ");
    }

    //层序遍历
    public void levelOrderTraversal(Node<E> node)
    {
        if (node == null) return;
        Queue<Node<E>> queue = new LinkedList<Node<E>>();
        queue.offer(node);
        while (!queue.isEmpty())
        {
            Node<E> node1 = queue.poll();
            System.out.print(node1.element+" ");
            if (node1.left != null) {
                queue.offer(node1.left);
            }
            if (node1.right != null) {
                queue.offer(node1.right);
            }
        }
    }

    public void postOrederTraversal()
    {
        postOrederTraversal(root);
    }

    //计算高度
    //递归

    private int getHight(Node<E> node)
    {
        if (node == null) return 0;
        return 1+Math.max(getHight(node.left),getHight(node.right));
    }

    public int height()
    {
        return getHight(root);
    }

    //迭代
    public int height2(Node<E> node)
    {
        if (node == null) return 0;

        //树的高度
        int height = 0;

        //存储的每一层的元素个数
        int levelSize = 1;
        Queue<Node<E>> queue = new LinkedList<Node<E>>();
        queue.offer(node);
        while (!queue.isEmpty()) {
            Node<E> node1 = queue.poll();
            levelSize--;

            if (node1.left != null) {
                queue.offer(node1.left);
            }
            if (node1.right != null) {
                queue.offer(node1.right);
            }

            if (levelSize == 0){  //意味着即将要访问下一层
                levelSize = queue.size();
                height++;
            }
        }
        return height;
    }


    //判断二叉树是否为完全二叉树
//    private boolean isComplete(Node<E> node)
//    {
//        if (node == null) return false;
//        Queue<Node<E>> queue = new LinkedList<Node<E>>();
//        boolean leafFlag = false;
//        queue.offer(root);
//        while(!queue.isEmpty())
//        {
//            Node<E> node1 = queue.poll();
//            if (leafFlag && !node1.isLeaf())
//            {
//                return false;
//            }
//            if (node1.hasTwoChild())  //有左右两个叶子节点
//            {
//                queue.offer(node1.left);
//                queue.offer(node1.right);
//            }
//            if (node1.left == null && node1.right != null)  //左子树为空,但是右子树不为空,不是完全二叉树
//            {
//                return false;
//            }
//            else {  //后面遍历的节点必须都是叶子节点   左右子树为空或者左子树不为空,右子树为空
//                leafFlag = true;
//                if ( node1.left !=null)
//                {
//                    queue.offer(node1.left);
//                }
//            }
//        }
//        return true;
//    }

    private boolean isComplete(Node<E> node)
    {
        if (node == null) return false;
        Queue<Node<E>> queue = new LinkedList<Node<E>>();
        boolean leafFlag = false;
        queue.offer(root);
        while(!queue.isEmpty())
        {
            Node<E> node1 = queue.poll();
            if (leafFlag && !node1.isLeaf()) {
                return false;
            }
            if (node1.left != null)
            {
                queue.offer(node1.left);
            }else if(node1.right !=null){
                //左边为空,右边不为空,不是完全二叉树
                return false;
            }
            if (node1.right != null)
            {
                queue.offer(node1.right);
            }else{
                leafFlag = true;
            }
        }
        return true;
    }

    public boolean isComplete()
    {
        return isComplete(root);
    }

    //二叉树的翻转
    public Node<E> invertTree(Node<E> node)
    {
//        if (node == null) return null;
//        Node<E> tmp = node.left;
//        node.left = node.right;
//        node.right = tmp;
//        invertTree(node.left);
//        invertTree(node.right);
//        return node;

        if (node == null) return null;
        Queue<Node<E>> queue = new LinkedList<Node<E>>();
        queue.offer(node);
        while (!queue.isEmpty())
        {
            Node<E> node1 = queue.poll();
            Node<E> tmp = node.left;
            node.left = node.right;
            node.right = tmp;
            if (node1.left != null) {
                queue.offer(node1.left);
            }
            if (node1.right != null) {
                queue.offer(node1.right);
            }
        }
        return node;
    }

    //获得二叉树的前驱节点 中序遍历的上一个节点
    public Node<E> predecessor(Node<E> node)
    {
        if (node == null) return null;
        //前驱节点在左子树中,(LRRRRRRRRRRR)
        //如果为二叉搜索树,则为左子树中的最大值,明显是 LRRRR...
        if (node.left != null) {
            Node<E> node1 = node.left;
            while (node1.right != null) {
                node1 = node1.right;
            }
            return node1;
        }
        //node在parent的右子树
        while (node.parent != null && node == node.parent.left)
        {
            node = node.parent;
        }
        return node.parent;
    }


    //获得二叉树的后驱节点
    public Node<E> successor(Node<E> node)
    {
        if (node == null) return null;
        //前驱节点在右子树中,(RLLLLLLLL)
        if (node.right != null) {
            Node<E> node1 = node.right;
            while (node1.left != null) {
                node1 = node1.left;
            }
            return node1;
        }
        //node在parent的左子树
        while (node.parent != null && node == node.parent.right)
        {
            node = node.parent;
        }
        return node.parent;
    }


    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        toString(root,stringBuilder," ");
        return stringBuilder.toString();
    }

    public void toString(Node<E> root,StringBuilder sb,String prefix)
    {
        if (root == null) return;
        sb.append(prefix).append(root.element).append("\n");
        toString(root.left,sb,prefix+"L");
        toString(root.right,sb,prefix+"R");
    }

    //java中的匿名类相当于ios中的block,JS中的闭包(function)

    public static void main(String[] args) {

        //可以定制比较规则
//        class PersonComparator implements Comparator<Person>
//        {
//            @Override
//            public int compare(Person e1, Person e2) {
//                return e1.age-e2.age;
//            }
//        }

//        BinarySearchTree<Person> searchTree = new BinarySearchTree<Person>(new PersonComparator());
//        Person person = new Person(22);
//        Person person1 = new Person(11);
//        searchTree.add(person);
//        searchTree.add(person1);
//
//        BinarySearchTree<Object> searchTree1 = new BinarySearchTree<>();
//        searchTree1.add(person1);
//        searchTree1.add(person);
        BinarySearchTree<Integer> searchTree2 = new BinarySearchTree<>();
        searchTree2.add(2);
        searchTree2.add(1);
        searchTree2.add(4);
        searchTree2.add(3);
        searchTree2.add(5);
        searchTree2.preOrederTraversal(searchTree2.root);
        System.out.println();
        searchTree2.inOrederTraversal();
        System.out.println();
        searchTree2.postOrederTraversal();
        System.out.println();
        searchTree2.levelOrderTraversal(searchTree2.root);
        System.out.println();
        searchTree2.levelOrder(new visitor<Integer>() {
            @Override
            public void visit(Integer element) {
                System.out.print("_"+element);
            }
        });
        System.out.println();
        System.out.println(searchTree2.toString());
        System.out.println(searchTree2.getHight(searchTree2.root));
        System.out.println(searchTree2.height2(searchTree2.root));
        System.out.println(searchTree2.isComplete());
        System.out.println(searchTree2.successor(searchTree2.root.right).element);
        searchTree2.remove(1);
        searchTree2.remove(2);
        searchTree2.inOrederTraversal();
        System.out.println(searchTree2.contains(3));
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值