注:文章中代码来自于何老师的代码,本文意在对于代码有更深的了解的解释文章
对于二叉搜索树中的node节点,定义为以下部分,key 是继承comparable<key> 可比较变量,value 为节点的内涵值,count为子节点的累加值,并且包含节点left & right,类的构造参数为key ,value
private class Node{
private Key key;
private Value val;
private int count;
private Node left,right;
public Node(Key key,Value val){
this.key=key;
this.val=val;
}
BST大类包含私有变量 root 作为根节点,其中size函数可以用来返回根节点的节点数
public int size()
{
return size( root);
}
private int size(Node x){
if (x==null) return 0;
return x.count;
}
get函数用来查找指定key的node在root为根的BST查找树中的value ,返回null or value
public Value get (Key key) {
Node x = root;
while (x != null) {
int cmp = key.compareTo(x.key);
if (cmp < 0) x = x.left;
else if (cmp > 0) x = x.right;
else if (cmp == 0) return x.val;
}
return null;
}
put函数用来插入指定key value的节点
当根节点为空的时候,则建立插入节点为根节点的查找树,
若根节点不为空且遍历中节点存在,则替换节点的value,
若根节点不为空且遍历中节点不存在,则将节点加入适当位置
之后根据stack的先进后出性质递归改变每个节点的count数
public void put(Key key, Value val)
{
root = put(root, key, val);
}
private Node put (Node x, Key key, Value val) {
if (x == null) return new Node(key, val,1);
int cmp = key.compareTo(x.key);
if (cmp < 0)
x.left = put(x.left, key, val);
else if (cmp > 0)
x.right = put(x.right, key, val);
else if (cmp == 0)
x.val = val;
x.count = 1 + size( x.left) + size( x.right);
return x;
}
floor 函数用来获得 the largest key <= the given key
ceiling 函数用来获得 the smallest key >=the given key
public Key floor(Key key) {
Node x = floor( root, key);
if (x == null) return null;
return x.key;
}
private Node floor (Node x, Key key) {
if (x == null) return null;
int cmp = key.compareTo(x.key);
if (cmp == 0) return x;
if (cmp < 0) return floor(x.left, key);
Node t = floor(x.right, key);
if (t != null) return t;
else return x;
}
rank函数用来求 the node number <=the given node
public int rank (Key key)
{
return rank(key, root);
}
private int rank (Key key, Node x) {
if (x == null) return 0;
int cmp = key.compareTo(x.key);
if (cmp < 0) return rank(key, x.left);
else if (cmp > 0) return 1 + size(x.left) + rank(key, x.right);
else return size(x.left);
}
遍历,包含先序遍历(preorder),中序遍历(inorder),后序遍历(postorder)三种,具体可参考https://blog.csdn.net/qq_41558173/article/details/105157051 简单来说,先序遍历为中左右,中序为左中右,后序遍历为左右中,即顺序取决于中间点的遍历顺序。
public Iterable<Key> keys()
{
Queue<Key> q=new Queue<>();
inorder(root,q);
return q;
}
private void inorder(Node x,Queue<Key> q) {
//中序遍历实例
if (x == null) return;
inorder(x.left, q);
q.enqueue(x.key);
inorder(x.right, q);
}
8.删除操作
public void delete(Key key)
{ root = delete(root, key); }
private Node delete (Node x, Key key) {
if (x == null) return null;
int cmp = key.compareTo(x.key);
if (cmp < 0) x.left = delete(x.left, key);
else if (cmp > 0) x.right = delete(x.right, key);
else {
if (x.right == null) return x.left;
if (x.left == null) return x.right;
Node t = x;
x = min(t.right);
x.right = deleteMin(t.right);
x.left = t.left;
}
x.count = size(x.left) + size(x.right) + 1;
return x;
}
private Node deleteMin(Node x){
if (x.left==null) return x.right;
x.left=deleteMin(x.left);
x.count = 1 + size(x.left) + size(x.right);
return x;
}
public Node min(Node x){
if (x.left!=null){
x=min(x.left);
}
return x;
}