数据结构-二叉查找树tree的简单实现

163 阅读3分钟
  • 观看数据结构简单的小总结,方便想起来咋回事
  • 这里写了二叉查找树的简易实现中的各个方法的简易解释
  • 树的定义:定义树的一种自然的方式是递归的方式。一棵树是一些节点的集合。这个集合可能是空集;若不是空集,则树由 根节点(root)和 0个或多个非空的(子)树T1,T2...组成

  • 嗯不说了 开始代码吧。。。
//二叉树 要求所有的项都能够排序,
//所以这里的 T 需要实现Comparable 接口,要可以进行 compareTo 比较大小的

public class MyBinaryTree<T extends Comparable<? super T>> {

    //这里的节点 与 链表类中的一样
    private static class BinaryNode<T> {
        T data;
        BinaryNode<T> left;
        BinaryNode<T> right;

        public BinaryNode(T data) {
            this(data, null, null);
        }

        public BinaryNode(T data, BinaryNode<T> left, BinaryNode<T> right) {
            this.data = data;
            this.left = left;
            this.right = right;
        }
    }

    //这是 根节点
    private BinaryNode<T> root;

    public MyBinaryTree() {
        root = null;
    }

    public void makeEmpty(){
        root = null;
    }
    public boolean isEmpty(){
        return root == null;
    }
    
    /**
     * 根据对比来获取是否是有t对应的数据在树中
     */
    public boolean contain(T t) {
        return contains(t, root);
    }

    private boolean contains(T t, BinaryNode<T> node) {
        if (node == null) return false;

        int compareTo = t.compareTo(node.data);
        
        //比较后,小于了,就递归的向当前node的左边(node.left) 继续寻找 t 
        //结束条件是node==null ->false 或者 compareTo==0 ->true
        if (compareTo < 0) {
            return contains(t, node.left);
        } else if (compareTo > 0) {
            return contains(t, node.right);
        } else {
            return true;
        }
    } 
    
     /**
     * 找到最小的 , 就是树的的最左边的节点
     */
    public T findMin() {
        if (root == null)
            throw new NullPointerException();
        return findMin(root).data;
    }
    private BinaryNode<T> findMin(BinaryNode<T> node) {

        if (node == null) {
            return null;
        }
        if (node.left == null) {
            return node;
        }
        return findMin(node.left);  //这里递归的寻找
    }

    /**
     * 找到最大的 , 就是树的的最右边的节点 这里用的是循环, 不是递归!
     */
    public T findMax() {
        if (root == null)
            throw new NullPointerException();
        return findMax(root).data;
    }
    private BinaryNode<T> findMax(BinaryNode<T> node) {
        if (node == null) {
            return null;
        }
        while (node.right != null) {
            node = node.right;
        }
        return node;
    }
  • 这里是插入的图示


  
    /**
     * 插入数据的时候,需要以root为开始,进行遍历对比插入,
     * 当第一次插入的时候 root == null , 所以第一次插入需要改变root的变化
     * 后面的就是需要 根据比较 node.data 来进行递归的将数据放到指定的位置
     * 结束是在node == null 的时候 将数据放到左右都为null的node中
     */
    public void insert(T t) {
        root = insert(t, root);
    }

    private BinaryNode<T> insert(T t, BinaryNode<T> node) {

        if (node == null) {
            return new BinaryNode<T>(t, null, null);
        }
        int compareTo = t.compareTo(node.data);

        if (compareTo < 0) {
            node.left = insert(t, node.left);
        } else if (compareTo > 0) {
            node.right = insert(t, node.right);
        } else {
            //todo 相等了放到一个集合里,或者更新data。。。
        }
        return node;
    }
    
  • 这是删除的图示

    public void remove(T t) {
        root = remove(t, root);
    }

    private BinaryNode<T> remove(T t, BinaryNode<T> node) {

        if (node == null) {
            return node;//todo
        }

        int compareTo = t.compareTo(node.data);
        if (compareTo < 0) {
            //往左边继续找
            node.left = remove(t, node.left);
        } else if (compareTo > 0) {
            //往右边继续找
            node.right = remove(t, node.right);
        } else if (node.left != null && node.right != null) {
            //这里找到了,
            //如果左右都不为空的话,将当前node的数据 改成 当前node下面的最小的node的数据
            node.data = findMin(node).data;
            //然后当前的node的右链表 = 把刚得到的 node.data 数据 从 node.right 开始查找进行删除
            node.right = remove(node.data, node.right);
        } else {
            //这里也找到了, 但是左右链表 中 有一个为空
            //如果左链 不为空,就将当前的node赋值为左链表 , 反之, 右链表。 也就是吧当前的 node进行了删除
            node = (node.left != null) ? node.left : node.right;
        }
        return node;
    }
  • 简单的遍历 和 深度获取
    /**
     * 遍历树
     */
    public void printTree() {
        if (root == null) {
            System.out.println("tree is empty ");
        } else {
            printTree(root);
        }
    }
    private void printTree(BinaryNode<T> node) {
        if (node != null) {
            printTree(node.left);
            System.out.print(node.data + " , ");
            printTree(node.right);
        }
    }

    /**
     * 获取树的高度,也可叫做 深度 。
     */
    public int height() {
        return height(root);
    }
    private int height(BinaryNode<T> node) {
        if (node == null)
            return -1;
        else
            return 1 + Math.max( height(node.left), height(node.right) );
    }