1.知识储备:
2.代码实现:
package Tree;
public class binaryTree<key extends Comparable<key>,value > {
//记录根节点
private Node root;
//记录元素个数
private int N=0;
//构造方法,初始化二叉树
public binaryTree(key key,value value,Node left,Node right) {
// TODO Auto-generated constructor stub
this.root=new Node(key, value, left, right);
this.N=1;
}
public binaryTree() {
// TODO Auto-generated constructor stub
}
private class Node{
//存储键
public key key;
//存储值
public value value;
//存储左节点
public Node left;
//存储右节点
public Node right;
//构造方法
public Node(key key,value value,Node left,Node right) {
// TODO Auto-generated constructor stub
this.key=key;
this.value=value;
this.left=left;
this.right=right;
}
}
//获取元素个数
public int size(){
return N;
}
//向树中添加元素,key-value
public void put(key key,value value){
root=put(root,key,value);
}
//向指定的树x中添加key-value,并返回添加元素后新的树
private Node put(Node x,key key,value value){
//如果x子树为空,则把新节点当作根节点使用
if(x==null){
N++;//元素个数+1
return new Node(key, value, null, null); //直接创建一个根节点并返回
}
int result=key.compareTo(x.key);
//如果x子树不为空,比较key的值,比当前节点小就往左放,比当前节点大就往右放
if(result>0){
//递归调用put直到找到根节点右侧合适的位置
x.right=put(x.right,key,value);
}else if(result<0){
//递归调用put直到找到根节点左侧合适的位置
x.left=put(x.left,key,value);
}else{
//等于当前节点就替换value即可
x.value=value;
}
return x;
}
//查询树中指定的值的value
public value get(key key){
return get(root,key);
}
//从指定的树x中,查找对应键的value值
public value get(Node x,key key){
//子树x为null,
if(x==null){
return null;
}
//子树x不为null
//创建result存储key值的比较结果
int result=key.compareTo(x.key);
//如果key值大于当前节点的key,则往右找
if(result>0){
return get(x.right,key);
}
//如果key值小于当前节点的key则往左找
else if(result<0){
return get(x.left,key);
}
//key等于当前节点的key则返回结果
else{
return x.value;
}
}
//删除树中key对应的value
public void delete(key key){
delete(root,key);
}
//删除指定树中key对应的value值,并返回删除后的新树
public Node delete(Node x,key key){
//x树为空
if(x==null){
return null;
}
//x树不为空
//创建result存储比较结果
int result=key.compareTo(x.key);
//如果result小于0则继续向左找
if(result<0){
x.left=delete(x.left,key);
}
//如果result>0则继续向右找
else if(result>0){
x.right=delete(x.right,key);
}
//如果result等于零,则找到该节点,完成删除即可
else{
//元素个数-1
N--; //一进来就是元素个数-1,避免出现bug,因为能进入到else里面来表面必定要删除一个元素
//首先得找到一个合适的节点来替换当前要删除的节点
//把目标节点定位右子树的最小节点
//第一步,如果左子树或右子树为空的情况
if(x.right==null){
return x.left;
}
if(x.left==null){
return x.right;
}
//如果左子树和右子树都不为空的话,就要遍历寻找右子树的最小节点
//创建一个最小节点变量,默认为让它等于当前节点的右子树节点
Node minNode=x.right;
//通过遍历来找到最小的节点
//顺着右子树的左边往下找,找到右子树最左边的叶子节点即可
while(minNode.left!=null){
minNode=minNode.left;
}
//将这个最小的节点先删除掉,然后再拿去替换真正要删除的节点
//先找到最小节点的父节点,方法是如果一个节点的左节点的左节点为空的话就是
Node n=x.right;
while(n.left!=null){
if(n.left.left==null){
n.left=null; //删除完成
}else{
//变换n节点即可
n=n.left;
}
}
//真正的删除x节点
//1.让x节点的左子树成为minNode的左子树
minNode.left=x.left;
//2.让x节点的右子树成为minNode的右子树
minNode.right=x.right;
//3.让x节点的父节点成为minNode的父节点
x=minNode;
}
return x;
}
}
3.测试类:
package Tree;
public class binaryTreeTest {
public static void main(String[] args) {
//创建二叉查找树
binaryTree<Integer,String> tree =new binaryTree<Integer, String>();
//测试插入
tree.put(1,"张三");
tree.put(2,"李四");
tree.put(3,"王五");
tree.put(4,"王五");
tree.put(8,"王五");
tree.put(6,"王五");
System.out.println("元素个数为:"+tree.size());
//测试获取
System.out.println("键2对应的元素是:"+tree.get(2));
//测试删除
tree.delete(3);
System.out.println("删除后的元素个数:"+tree.size());
System.out.println("删除后的key3对应的元素:"+tree.get(3));
}
}
4.测试结果: