/*基于二叉查找树的符号表*/
public class BST<Key extends Comparable<Key>, Value> {
// 根结点
private Node root;
// 定义一个内部结点类
private class Node{
private Key key; // 键
private Value val; // 值
private Node left, right; // 指向子树的链接
private int n; // 结点计数器
public Node(Key key, Value val, int n){
this.key = key;
this.val = val;
this.n = n;
}
}
public int size() {
return size(root);
}
private int size(Node x) {
if (x == null) {
return 0;
}
return x.n;
}
// 二叉查找树的查找和排序方法的实现
public Value get(Key key) {
return get(root, key);
}
public Value get(Node x, Key key) {
// 如果找不到则返回null
if (x == null) {
return null;
}
int cmp = key.compareTo(x.key);
if (cmp > 0) {
return get(x.right, key);
}else if (cmp < 0) {
return get(x.left, key);
}else {
return x.val;
}
}
public void put(Key key, Value val) {
// 查找key,找到则更新它的值,否则为它创建一个新的结点
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 {
// 查找命中,更新值
x.val = val;
}
x.n = size(x.left) + size(x.right) + 1;
return x;
}
// 最小键
public Key min() {
return min(root).key;
}
private Node min(Node x) {
if (x.left == null) {
return x;
}
return min(x.left);
}
// 最大键
public Key max() {
return max(root).key;
}
private Node max(Node x) {
if (x.right == null) {
return x;
}
return max(x.right);
}
// 向下取整
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;
}
}
// 找到排名为k的键(即树中正好有k个小于它的键)
public Key select(int k) {
return select(root, k).key;
}
private Node select(Node x, int k) {
// 返回排名为k的节点
if (x == null) {
return null;
}
int t = size(x.left);
if (t > k) {
return select(x.left, k);
}else if (t < k) {
return select(x.right, k-t-1);
}else {
return x;
}
}
// 计算给定键的排名
public int rank(Key key) {
return rank(key, root);
}
private int rank(Key key, Node x) {
// 返回以x为根节点的子树中小于x.key的键的数量
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);
}
}
// 二叉查找树的删除最小结点方法
public void deleteMin() {
root = deleteMin(root);
}
private Node deleteMin(Node x) {
if (x.left == null) {
return x.right;
}
x.left = deleteMin(x.left);
x.n = size(x.left) + size(x.right) + 1;
return x;
}
// 二叉查找树的删除操作
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指向它的后继节点
x = min(t.right);
x.right = deleteMin(t.right);
x.left = t.left;
}
// 更新结点计数器的值
x.n = size(x.left) + size(x.right) + 1;
return x;
}
// 二叉查找树的范围查找操作
public Iterable<Key> keys() {
return keys(min(), max());
}
public Iterable<Key> keys(Key lo, Key hi) {
Queue<Key> queue = new Queue<>();
keys(root, queue, lo, hi);
return queue;
}
private void keys(Node x, Queue<Key> queue, Key lo, Key hi) {
if (x == null) {
return;
}
int cmplo = lo.compareTo(x.key);
int cmphi = hi.compareTo(x.key);
if (cmplo < 0) {
keys(x.left, queue, lo, hi);
}
if (cmplo <= 0 && cmphi >= 0) {
queue.enqueue(x.key);
}
if (cmphi > 0) {
keys(x.right, queue, lo, hi);
}
}
}
BST
最新推荐文章于 2024-09-23 22:27:40 发布