二叉树的结点类:
二叉树就是一个一个的结点及其之间的关系组成的,按照面向对象的思想,我们设计一个结点类来描述结点这个事物。
结点类的API设计:
代码实现:
package com.yyy;
public class Node<Key,Value> {
//记录左子结点
private Node left;
//记录右子结点
private Node right;
//存储键
private Key key;
//存储值
private Value value;
public Node(Key key,Value value,Node left,Node right){
this.key=key;
this.value=value;
this.left=left;
this.right=right;
}
}
二叉查找树的API设计:
代码实现:
package com.yyy;
public class BinaryTree<Key extends Comparable<Key>,Value> {
//记录根结点
private Node root;
//记录树中元素的个数
private int N;
//创建对象,初始化
public BinaryTree(){
// this.root=new Node(null,null,null,null);
this.root=null;
this.N=0;
}
public class Node {
//存储键
public Key key;
//存储值
private Value value;
//记录左子结点
public Node left;
//记录右子结点
public Node right;
public Node(Key key, Value value, Node left, Node right) {
this.key = key;
this.value = value;
this.left = left;
this.right = right;
}
}
//获取树中元素的个数
public int size(){
return N;
}
//向树中插入一个键值对
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++;
return new Node(key,value,null,null);
}
//如果x子树不为空
//比较x结点的键和key的大小:
int cmp = key.compareTo(x.key);
if(cmp>0){
//如果Key大于X结点的键,则继续找x结点的右子树
x.right=put(x.right,key,value);
}else if(cmp<0){
//如果key小于x结点的键,则继续找x结点的左子树
x.left=put(x.left,key,value);
}else{
//如果key等于x结点的键,则替换x结点的值即可
x.value=value;
}
return x;
}
//查询树中指定key对应的value
public Value get(Key key) {
return get(root,key);
}
//从指定的树中,查找key对应的值
private Value get(Node x,Key key){
//如果x树为Null
if(x==null){
return null;
}
//如果x树不为空,比较与根结点的值
int cmp = key.compareTo(x.key);
if(cmp>0){
//如果key大于x结点的键,则继续找x结点的右子树
return get(x.right,key);
}else if(cmp<0){
//如果key小于x结点的键,则继续找x结点的左子树
return get(x.left,key);
}else{
return x.value;
}
}
//删除树中key对应结点
public void delete(Key key){
delete(root,key);
}
//删除指定树x中的key对应的value,并返回删除后的新树
private Node delete(Node x, Key key) {
//x树为Null
if(x==null){
return null;
}
//x树不为Null
int cmp=key.compareTo((Key) x.key);
if(cmp>0){
//如果Key大于x结点的键,则继续找x结点的右子树
x.right=delete(x.right,key);
}else if(cmp<0){
//如果Key小于x结点的键,则继续找x结点的左子树
x.left=delete(x.left,key);
}else{
//如果key等于x结点的键,完成真正的删除结点动作,要删除的结点就是x
//让元素个数减1
N--;
//找到右子树中最小的结点
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结点的左子树成为minNdoe的左子树
minNode.left=x.left;
//让x结点的右子树成为minNode的右子树
minNode.right=x.right;
//让x结点的父结点指向minNode
x=minNode;
}
return x;
}
}
测试代码:
package test;
import com.yyy.BinaryTree;
public class BinaryTreeTest {
public static void main(String[] args) {
BinaryTree <Integer, String> binaryTree = new BinaryTree <>();
binaryTree.put(1,"王二");
binaryTree.put(2,"张三");
binaryTree.put(3,"李四");
binaryTree.put(4,"王五");
System.out.println(binaryTree.get(3)+"==========="+binaryTree.size());
binaryTree.delete(3);
System.out.println(binaryTree.get(3)+"==========="+binaryTree.size());
}
}