数据结构 -- 二叉排序树

在这里插入图片描述

package com.mybatis.test;

import java.nio.BufferUnderflowException;

/**
 * @ClassName BinarySearchTree
 * @Description
 * @Author 
 * @Date 2019/10/19 0:01
 * @Version 1.0
 **/
public class BinarySearchTree<T extends Comparable<? super T>> {
    //成员变量
    private BinaryNode<T> root;

    public BinarySearchTree(){
        root = null;
    }

    public void makeEmpty(){
        root = null;
    }

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

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

    public T findMin(){
        if(isEmpty())
            throw new BufferUnderflowException();
        return findMin(root).element;
    }

    public T findMax(){
        if(isEmpty())
            throw new BufferUnderflowException();
        return findMax(root).element;
    }

    //节点类
    private static class BinaryNode<T>{
        T element;
        BinaryNode<T> left;
        BinaryNode<T> right;
        BinaryNode(T theElement,BinaryNode<T> lt,BinaryNode<T> rt){
            element = theElement;
            left = lt;
            right = rt;
        }
    }

    /**
     * 私有方法
     */
    //树中是否包含x节点
    private boolean contains(T x,BinaryNode<T> t){
        if(t == null)
            return false;
        int compareResult = x.compareTo(t.element);
        if(compareResult < 0)
            return contains(x,t.left);
        else if(compareResult > 0)
            return contains(x,t.right);
        else
            return true;
    }
    //插入节点
    private BinaryNode<T> insert(T x,BinaryNode<T> t){
        if(t == null)
            return new BinaryNode<T>(x,null,null);
        int comapareResult = x.compareTo(t.element);
        if(comapareResult < 0)
            t.left = insert(x,t.left);
        else if(comapareResult > 0)
            t.right = insert(x,t.right);
        return t;
    }
    //删除
    private BinaryNode<T> remove(T x,BinaryNode<T> t){
        if(t == null)
            return t;
        int compareResult = x.compareTo(t.element);
        if(compareResult < 0)
            t.left = remove(x,t.left);
        else if(compareResult > 0)
            t.right = remove(x,t.right);
        else if(t.left!=null&&t.right!=null){
            t.element = findMin(t.right).element;
            t.right = remove(t.element,t.right);
        }else
            t = (t.left!=null)?t.left:t.right;
        return t;
    }
    //查找最小
    private BinaryNode<T> findMin(BinaryNode<T> t){
        if(t == null)
            return null;
        else if(t.left == null)
            return t;
        return findMin(t);
    }
    //查找到最大
    private BinaryNode<T> findMax(BinaryNode<T> t){
        if(t!=null)
            while(t.right != null)
                t = t.right;
        return t;
    }
}

1、节点类

  • 这里是一个内部类。
private static class BinaryNode<T>{
        T element;
        BinaryNode<T> left;
        BinaryNode<T> right;
        BinaryNode(T theElement,BinaryNode<T> lt,BinaryNode<T> rt){
            element = theElement;
            left = lt;
            right = rt;
        }
    }

其中值用T这样泛型来表示(建议测试的时候用Integer类型),其中element表示该节点的值,left和right分别表示左右孩子。构造函数,初始化节点。

2、成员变量和简单方法

  • 这里面根节点是root,构造函数设置root为空,makeEmpty设置节点值是空,isEmpty判断当前root是否是空。
//成员变量
    private BinaryNode<T> root;

    public BinarySearchTree(){
        root = null;
    }

    public void makeEmpty(){
        root = null;
    }

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

3、私有contains方法

private boolean contains(T x,BinaryNode<T> t){
    if(t == null)
        return false;
    int compareResult = x.compareTo(t.element);
    if(compareResult < 0)
        return contains(x,t.left);
    else if(compareResult > 0)
        return contains(x,t.right);
    else
        return true;
}
  • 判断x是否在这个t树内。
  • 如果这个树是空,直接返回。
  • 利用compareTo 这个方法,判断比较后的结果,如果小于零,该节点的值继续与左子树的值递归比较。如果大于零,该节点的值继续与右子树的值进行比较。如果有相同的就返回true。

4、私有insert方法

private BinaryNode<T> insert(T x,BinaryNode<T> t){
   if(t == null)
        return new BinaryNode<T>(x,null,null);
    int comapareResult = x.compareTo(t.element);
    if(comapareResult < 0)
        t.left = insert(x,t.left);
    else if(comapareResult > 0)
        t.right = insert(x,t.right);
    return t;
}
  • 如果当前的树是空值,就直接新建一个节点,值为x。
  • 如果树不是空值,那么与值相比较,如果小于零,说明需要插入到左子树,如果大于零则需要插入右子树。
  • 最后一定会遇到一个t = null的情况,那么就创建节点,返回数据,这时t.left或者t.right会接收。插入完成。

5、私有remove方法

private BinaryNode<T> remove(T x,BinaryNode<T> t){
    if(t == null)
        return t;
    int compareResult = x.compareTo(t.element);
    if(compareResult < 0)
        t.left = remove(x,t.left);
    else if(compareResult > 0)
        t.right = remove(x,t.right);
    else if(t.left!=null&&t.right!=null){
    //删除两个孩子
        t.element = findMin(t.right).element;
        t.right = remove(t.element,t.right);
    }else
    //删除一个孩子
        t = (t.left!=null)?t.left:t.right;
    return t;
}
  • 删除这个有点复杂,这里一共分为三种情况:
  • 1、如果删除的是叶子节点,直接删除
  • 2、如果删除的节点t有一个孩子,那么直接将t = (t.left!=null)?t.left:t.right,即可将t = t.left或者t = t.right。
  • 3、如果删除的节点t有两个孩子,那么将查找t的左子树的最小节点的值付给t的值,然后然后删除这个最小节点。

6、查找最大查找最小

 //查找最小
private BinaryNode<T> findMin(BinaryNode<T> t){
    if(t == null)
        return null;
    else if(t.left == null)
        return t;
    return findMin(t);
}
//查找到最大
private BinaryNode<T> findMax(BinaryNode<T> t){
    if(t!=null)
        while(t.right != null)
            t = t.right;
    return t;
}
  • 这个也比较容易懂!!

7、剩余方法

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

public T findMin(){
   if(isEmpty())
       throw new BufferUnderflowException();
   return findMin(root).element;
}

public T findMax(){
   if(isEmpty())
       throw new BufferUnderflowException();
   return findMax(root).element;
}
  • 最后都是调用方法了。
发布了134 篇原创文章 · 获赞 91 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/weixin_44588495/article/details/102655842