二叉查找树是树中最基础的,具有如下定义:
1.每个根节点最多拥有2个子节点;
2.子节点分为左子节点和右子节点,假设根节点为x,左子节点为y,右子节点为z,则必须满足z>x>y;
根据如上的定义可以有如下推论:
1.高度为n的二叉树最多由个结点构成,故而,二叉树的平均深度是;
2.一个结点左边的所有子节点都小于它,右边则大于它;
对于二叉查找树而言,查找元素是十分快速的,每次查找都会由根结点入手,判断是否相等,相等则皆大欢喜,如果大于则往右边找,小于则往左边找,每次向下查找都会使得深度加1,对于n个数据来说,二叉树平均深度为,所以该查找方法的平均算法复杂度即为。
实现BST的程序如下:
package A02.Tree;
public class BST<E extends Comparable<? super E>>
{
// 测试方法
public static void main(String[] args)
{
BST<Integer> bst = new BST<>();
bst.insert(3);
bst.insert(7);
bst.insert(3);
bst.insert(4);
bst.insert(1);
bst.disPlay();
for (int i = 0; i < 10; i++)
{
System.out.println(i + "是否找到?" + bst.findData(i));
}
System.out.println("min=" + bst.getMin());
bst.remove(3);
bst.remove(1);
bst.remove(7);
bst.disPlay();
}
private Node<E> root;
private int size;
public boolean findData(E data)
{
return findData(data, root);
}
// 获取根节点
public E getRoot()
{
if (root == null)
return null;
return root.data;
}
// 获取最小值
public E getMin()
{
if (root == null)
return null;
return getMin(root);
}
public E getMin(Node<E> root)
{
if (root.left != null)
return getMin(root.left);
return root.data;
}
private boolean findData(E data, Node<E> root)
{
if (root == null)
return false;
int result = data.compareTo(root.data);
if (result > 0)
return findData(data, root.rigth);
else if (result < 0)
return findData(data, root.left);
return true;
}
public void insert(E data)
{
size++;
root = insert(data, root);
}
public Node<E> insert(E data, Node<E> root)
{
if (root == null)
return new Node<>(data, null, null);
int result = data.compareTo(root.data);
if (result > 0)
root.rigth = insert(data, root.rigth);
else if (result < 0)
root.left = insert(data, root.left);
else
size--;
return root;
}
public void disPlay()
{
if (root != null)
disPlay(root);
}
private void disPlay(Node<E> root)
{
if (root.left != null)
disPlay(root.left);
System.out.println(root.data);
if (root.rigth != null)
disPlay(root.rigth);
}
public void remove(E data)
{
if (findData(data))
{
remove(data, root);
size--;
}
}
private Node<E> remove(E data, Node<E> root)
{
int result = data.compareTo(root.data);
if (result > 0)
root.rigth = remove(data, root.rigth);
if (result < 0)
root.left = remove(data, root.left);
else if (root.left != null && root.rigth != null)
{
// 用删除节点右方最小子节点来顶替它的位置
root.data = getMin(root.rigth);
// 此时假设顶替过来的节点为K,则现存两个相同的K,需要把原来的K删除
root.rigth = remove(root.data, root.rigth);
} else
root = (root.left != null) ? root.left : root.rigth;
return root;
}
public int size()
{
return size;
}
private class Node<E>
{
E data;
Node<E> left;
Node<E> rigth;
public Node(E data, Node<E> left, Node<E> rigth)
{
this.data = data;
this.left = left;
this.rigth = rigth;
}
}
}
程序中大量使用了递归,而非循环,这样做的目的是使得程序根据简洁易读。