实现:
import java.util.LinkedList;
/**
*
* Online LCA algorithm
* complexity:
*
* see also: B. Schieber & U. Vishkin (1988) "On finding lowest common ancestors - Simplification and parallelization"
*
* Copyright (c) 2011 ljs (http://blog.csdn.net/ljsspace/)
* Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
*
*
* @author ljs
* 2011-08-23
*
*/
public class OnlineLCA {
static class Node{
int key;
Node[] children;
Node parent;
int inlabel;
int ascendant;
int level;
public Node(int key){
this.key = key;
}
public String toString() {
return String.valueOf(key) + " parent:" +
(this.parent==null?"":this.parent.key) +
" inlabel:" + inlabel + " level:" + level +
" ascendant:" + ascendant;
}
}
//the leaders of each inlabel path
private Node[] HEAD;
//the bits of inlabel and ascendent
private int l;
private Node root;
public OnlineLCA(int n,Node root){
HEAD = new Node[n+1];
this.root = root;
l = (int)(Math.log(n) / Math.log(2));
}
//preprocess tree T
public void preprocess(){
this.root.level = 0;
doInOrderTraverse(this.root);
doLevelOrderTraverse();
}
//return the LCA node of x and y
public Node query(Node x,Node y){
Node lca = null;
if(x.inlabel==y.inlabel){
if(x.leveli)
i=tmp;
int diff = x.inlabel ^ y.inlabel;
tmp = (int)(Math.log(diff) / Math.log(2));
if(tmp>i)
i=tmp;
//find j and z.inlabel (z is lca of x and y)
int ascand = x.ascendant & y.ascendant;
int j = findLSBOne(ascand,i);
int inlabelz = findInlabel(x,j);
//find x-hat and y-hat
Node x_hat = findHat(x,inlabelz,j);
Node y_hat = findHat(y,inlabelz,j);
if(x_hat.level>= rightStart;
while((num & 0x01) != 0x01){
num >>=1;
i++;
}
return i;
}
//calculate ascendants and head based on inlabel numbers
//so this method must be called after inlabels are determined.
private void doLevelOrderTraverse(){
LinkedList queue = new LinkedList();
queue.add(this.root);
HEAD[this.root.inlabel] = this.root;
this.root.ascendant = (1<
测试:
LCA of 30 and 40 is: 20
LCA of 30 and 100 is: 10
LCA of 70 and 100 is: 50
LCA of 80 and 90 is: 80
LCA of 70 and 80 is: 50
LCA of 100 and 90 is: 80
LCA of 50 and 100 is: 50
************************
LCA of 40 and 70 is: 30
LCA of 170 and 180 is: 150
LCA of 90 and 220 is: 10
LCA of 130 and 200 is: 130
LCA of 160 and 220 is: 150
LCA of 200 and 210 is: 190
LCA of 120 and 190 is: 10
LCA of 50 and 80 is: 30
LCA of 40 and 110 is: 10
LCA of 60 and 100 is: 30
LCA of 30 and 200 is: 10
LCA of 60 and 190 is: 10
LCA of 10 and 50 is: 10
LCA of 20 and 50 is: 20
LCA of 50 and 90 is: 30
LCA of 30 and 150 is: 10
你可能感兴趣的:(数据结构和算法)