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;
}
}
b、二叉查找树实现
插入方法(put)实现思想:
- 如果当前书中没有任何一个结点,则直接把新节点当做根节点使用
- 如果当前树不为空,则从根节点开始:
- 如果新结点的key小于当前结点的key,则继续找当前结点的左子结点
- 如果新结点的key大于当前结点的key,则继续找当前结点的右子结点
- 如果新结点的key等于当前结点的key,则树中已经存在这样的结点,替换该结点的value值
流程图如下:
查询(get)实现思想:
从根节点开始:
- 如果要查询的key小于当前结点的key,则继续找当前结点的左子结点
- 如果要查询的key大于当前结点的key,则继续找当前结点的右子结点
- 如果要查询的key等于当前结点的key,则返回当前结点的value
删除方法delete实现思想:
- 找到被删除结点
- 找到被删除结点右子树的最小结点minNode
- 删除右子树中的最小结点
- 让被删除结点的左子树称为最小结点minNode的左子树,让被删除结点的右子树称为最小结点minNode的右子树
- 让被删除结点的父节点指向最小结点minNode
完整代码
//二叉树代码
class BinaryTree<Key extends Comparable<Key>, Value> {
//记录根结点
private Node root;
//记录树中元素的个数
private int N;
//获取树中元素的个数
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) {
if (x == null) {
//个数+1
N++;
return new Node(key, value, null, null);
}
int cmp = key.compareTo(x.key);
if (cmp > 0) {
//新结点的key大于当前结点的key,继续找当前结点的右子结点
x.right = put(x.right, key, value);
} else if (cmp < 0) {
//新结点的key小于当前结点的key,继续找当前结点的左子结点
x.left = put(x.left, key, value);
} else {
//新结点的key等于当前结点的key,把当前结点的value进行替换
x.value = value;
}
return x;
}
//查询树中指定key对应的value
public Value get(Key key) {
return get(root, key);
}
//从指定的树x中,查找key对应的值
public Value get(Node x, Key key) {
if (x == null) {
return null;
}
int cmp = key.compareTo(x.key);
if (cmp > 0) {
//如果要查询的key大于当前结点的key,则继续找当前结点的右子结点;
return get(x.right, key);
} else if (cmp < 0) {
//如果要查询的key小于当前结点的key,则继续找当前结点的左子结点;
return get(x.left, key);
} else {
//如果要查询的key等于当前结点的key,则树中返回当前结点的value。
return x.value;
}
}
//删除树中key对应的value
public void delete(Key key) {
root = delete(root, key);
}
//删除指定树x中的key对应的value,并返回删除后的新树
public Node delete(Node x, Key key) {
if (x == null) {
return null;
}
int cmp = key.compareTo(x.key);
if (cmp > 0) {
//新结点的key大于当前结点的key,继续找当前结点的右子结点
x.right = delete(x.right, key);
} else if (cmp < 0) {
//新结点的key小于当前结点的key,继续找当前结点的左子结点
x.left = delete(x.left, key);
} else {
//新结点的key等于当前结点的key,当前x就是要删除的结点
//1.如果当前结点的右子树不存在,则直接返回当前结点的左子结点
if (x.right == null) {
return x.left;
}
//2.如果当前结点的左子树不存在,则直接返回当前结点的右子结点
if (x.left == null) {
return x.right;
}
//3.当前结点的左右子树都存在
//3.1找到右子树中最小的结点
Node minNode = x.right;
while (minNode.left != null) {
minNode = minNode.left;
}
//3.2删除右子树中最小的结点
Node n = x.right;
while (n.left != null) {
if (n.left.left == null) {
n.left = null;
} else {
n = n.left;
}
}
//3.3让被删除结点的左子树称为最小结点minNode的左子树,让被删除结点的右子树称为最小结点minNode的右子树
minNode.left = x.left;
minNode.right = x.right;
//3.4让被删除结点的父节点指向最小结点minNode
x = minNode;
//个数-1
N--;
}
return x;
}
private 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 class Test {
public static void main(String[] args) throws Exception {
BinaryTree<Integer, String> bt = new BinaryTree<>();
bt.put(4, "二哈");
bt.put(1, "张三");
bt.put(3, "李四");
bt.put(5, "王五");
System.out.println(bt.size());
bt.put(1,"老三");
System.out.println(bt.get(4));
bt.put(2, "小屋");
System.out.println(bt.size());
bt.delete(2);
System.out.println(bt.size());
}
}
转载:https://blog.csdn.net/CSDN_little_H/article/details/125696347