我们讲解二分搜索树前,我们先讲一下什么是二叉树
这样的结构就是二叉树
二叉树有什么特点呢?
- 只有一个根节点
- 每个节点的子节点最多只有两个
那么根据上面的定义下面也是二叉树
什么是满二叉树
除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。
什么是二分搜索树呢
- 二叉树
- 每个节点的值大于左子树上所有节点的值
- 每个节点的值小于右子树上所有节点的值
- 每个子树也是二分搜索树
- 二分搜索树不一定是满二叉树
- 存储的元素必须具有可比性
如果我们要设计成可以存储重复元素的二叉树,我们可以定义每个节点的值大于等于左子树上所有节点的值或者每个节点的值小于等于右子树上所有节点的值。来达到存储重复元素。
下面我们来实现一个二分搜索树
package com.yuanxuzhen.tree;
/**
* 二分搜索树的特点
* 1、二叉树
* 2、节点具有可比较性
* 3、左子树的节点值 < 根节点的值 < 右子树的节点值
* 4、每个子树也是二分搜索树
* 5、二分搜索树不一定是满二叉树
*
* 注意:我们的二分搜索树设计为没有重复元素
* @param <T>
*/
public class YuanBST<T extends Comparable<T>> {
private class Node{
Node left;
Node right;
T entry;
public Node(T entry) {
this.entry = entry;
this.left = null;
this.right = null;
}
}
//root 二分搜索树的根节点
private Node root;
//size 二分搜索树的节点个数
private int size;
public YuanBST() {
this.root = null;
this.size = 0;
}
/**
* 获取二分搜索树的节点个数
* @return
*/
public int size(){
return size;
}
public boolean isEmpty(){
return size == 0;
}
/**
*向二分搜索树中添加节点
* @param entry
*/
public void add(T entry){
/**
* 根节点如果为空,直接新建一个Node节点,做为根节点
* 根节点不为空,那么就将元素添加进二分搜索树中。由于每个子节点,都可以看做是二分搜索树,那么我们就可以使用递归进行添加
*/
// if(root == null){
// root = new Node(entry);
// }else{
// add(root, entry);
// }
root = addV1(root, entry);
}
private void add(Node node, T entry){
//递归最重要的是结束条件
if(entry.compareTo(node.entry) == 0){
//我们的二分搜索树设计为没有重复元素
return;
}else if(entry.compareTo(node.entry) < 0 && node.left == null){
//如果插入的元素小于节点值且左子树为null,那么直接创建节点,作为左节点
node.left = new Node(entry);
++size;
return;
}else if(entry.compareTo(node.entry) > 0 && node.right == null){
//如果插入的元素大于于节点值且右子树为null,那么直接创建节点,作为右节点
node.right = new Node(entry);
++size;
return;
}
if(entry.compareTo(node.entry) < 0){
//如果插入的元素小于节点值,且左子树不为空,递归插入左子树
add(node.left, entry);
}else{
//如果插入的元素大于节点值,且右子树不为空,递归插入右子树
add(node.right, entry);
}
}
private Node addV1(Node node, T entry){
//null可以看做是二叉树
if(node == null){
++size;
return new Node(entry);
}
if(entry.compareTo(node.entry) < 0){
//如果插入的元素小于节点值,且左子树不为空,递归插入左子树
node.left = addV1(node.left, entry);
}else if(entry.compareTo(node.entry) > 0){
//如果插入的元素大于节点值,且右子树不为空,递归插入右子树
node.right = addV1(node.right, entry);
}
return node;
}
}
我们先实现了将数据添加进树中,通过递归的方法。上面很详细的写了注释。