我正在阅读Introduction to Algorithms by Cormen第14章(增强数据结构),其中他正在谈论间隔树。以下是他提到的区间树背后的设计方法。
第1步:基础数据结构
我们选择一个红黑树,其中每个节点 x 包含一个间隔 x:int , x 的键是低的间隔的端点, x.int.low 。因此,数据结构的顺序树遍历按低端点按排序顺序列出间隔。
这可以通过声明具有 min 和 max 的节点来完成。 comparativeTo 函数应仅比较 x.int.low 。
第2步:其他信息
除了间隔本身,每个节点 x 都包含一个值 x.max ,它是存储在子树中的任何间隔端点的最大值。在 x 。
第3步:维护信息
我们必须验证插入和删除是否在n个节点的间隔树上占用 O(lg n)时间。我们可以确定给定间隔 x.int 的 x.max 以及节点 x 的子节点的 max 值:
x:max = max(x.int.high; x.left.max; x.right.max)
第4步:开发新业务
我们需要的唯一新操作是
INTERVAL-SEARCH
( T , i ),它在树 T 中找到一个节点,其中区间重叠区间 i 。如果树中没有与 i 重叠的间隔,则该过程返回指向sentinel T:nil 的指针。
我可以通过 AVL树实现这一点,但出于好奇,我们想知道我们是否可以像在 TreeSet 或其他集合实体中那样扩充Java中的现有库适合上述设计。如果是这样,您能帮助您提供示例代码或示例吗?
答案 0 :(得分:2)
我的区间树实施AVL tree。
public class IntervalTreeAVL<T>{
private static class TreeNode<T>{
private T low;
private T high;
private TreeNode<T> left;
private TreeNode<T> right;
private T max;
private int height;
private TreeNode(T l, T h){
this.low=l;
this.high=h;
this.max=high;
this.height=1;
}
}
private TreeNode<T> root;
public void insert(T l, T h){
root=insert(root, l, h);
}
private TreeNode<T> insert(TreeNode<T> node, T l, T h){
if(node==null){
return new TreeNode<T>(l, h);
}
else{
int k=((Comparable)node.low).compareTo(l);
if(k>0){
node.left=insert(node.left, l, h);
}
else{
node.right=insert(node.right, l, h);
}
node.height=Math.max(height(node.left), height(node.right))+1;
node.max=findMax(node);
int hd = heightDiff(node);
if(hd<-1){
int kk=heightDiff(node.right);
if(kk>0){
node.right=rightRotate(node.right);
return leftRotate(node);
}
else{
return leftRotate(node);
}
}
else if(hd>1){
if(heightDiff(node.left)<0){
node.left = leftRotate(node.left);
return rightRotate(node);
}
else{
return rightRotate(node);
}
}
else;
}
return node;
}
private TreeNode<T> leftRotate(TreeNode<T> n){
TreeNode<T> r = n.right;
n.right = r.left;
r.left=n;
n.height=Math.max(height(n.left), height(n.right))+1;
r.height=Math.max(height(r.left), height(r.right))+1;
n.max=findMax(n);
r.max=findMax(r);
return r;
}
private TreeNode<T> rightRotate(TreeNode<T> n){
TreeNode<T> r = n.left;
n.left = r.right;
r.right=n;
n.height=Math.max(height(n.left), height(n.right))+1;
r.height=Math.max(height(r.left), height(r.right))+1;
n.max=findMax(n);
r.max=findMax(r);
return r;
}
private int heightDiff(TreeNode<T> a){
if(a==null){
return 0;
}
return height(a.left)-height(a.right);
}
private int height(TreeNode<T> a){
if(a==null){
return 0;
}
return a.height;
}
private T findMax(TreeNode<T> n){
if(n.left==null && n.right==null){
return n.max;
}
if(n.left==null){
if(((Comparable)n.right.max).compareTo(n.max)>0){
return n.right.max;
}
else{
return n.max;
}
}
if(n.right==null){
if(((Comparable)n.left.max).compareTo(n.max)>0){
return n.left.max;
}
else{
return n.max;
}
}
Comparable c1 = (Comparable)n.left.max;
Comparable c2 = (Comparable)n.right.max;
Comparable c3 = (Comparable)n.max;
T max=null;
if(c1.compareTo(c2)<0){
max=n.right.max;
}
else{
max=n.left.max;
}
if(c3.compareTo((Comparable)max)>0){
max=n.max;
}
return max;
}
TreeNode intervalSearch(T t1){
TreeNode<T> t = root;
while(t!=null && !isInside(t, t1)){
if(t.left!=null){
if(((Comparable)t.left.max).compareTo(t1)>0){
t=t.left;
}
else{
t=t.right;
}
}
else{
t=t.right;
}
}
return t;
}
private boolean isInside(TreeNode<T> node, T t){
Comparable cLow=(Comparable)node.low;
Comparable cHigh=(Comparable)node.high;
int i = cLow.compareTo(t);
int j = cHigh.compareTo(t);
if(i<=0 && j>=0){
return true;
}
return false;
}
}