有一种情况暂未解决,当一个至少含2个结点的连通分量X,要合并到另外的连通分量上去的情况:
没有更新X的所有结点的深度值。
但当只含一个结点的连通分量X,要合并到另外的连通分量上去的情况,不存在问题。
package com.example.kevintest.demo.zx;
import java.util.HashMap;
public class Test2 {
//保存节点i的高度
static HashMap<String , Integer> high = new HashMap<>();
/*
* 判断是否有连通
* */
public static boolean checkIsConnect(HashMap<String , String> h , String p1 , String p2) {
String bossP1 = findBoss(h , p1);
String bossP2 = findBoss(h , p2);
return bossP1 == bossP2;
}
/*
* 查找p的最大boss
* */
public static String findBoss(HashMap<String , String> h , String p) {
while(true) {
if(h.get(p) == null) {
return p;
}
p = h.get(p);
}
}
/*
* 是否是直系关系
* */
public static int isZX(HashMap<String , String> h , String p1 , String p2) {
int len = 0;
int isok = 0;
String tmp_p1 = p1;
while(true) {
if(h.get(p1) == null) {
break;
}
if(h.get(p1) == p2) {
isok = 1;
break;
} else {
p1 = h.get(p1);
len++;
}
}
if(isok == 1) {
return len+1;
} else {
//归位
p1 = tmp_p1;
len = 0;
while(true) {
if(h.get(p2) == null) {
break;
}
//System.out.println(h.get(p2));
if(h.get(p2) == p1) {
isok = 1;
break;
} else {
p2 = h.get(p2);
len++;
}
}
if(isok == 1) {
return len+1;
} else {
return -1;
}
}
}
/*
* 获得p1和p2的关系
* */
public static Object GetGeneration(HashMap<String , String> h , String p1 , String p2) {
//有直系连接
int len = isZX(h , p1 , p2);
if(len != -1) {
return len;
}
//不是直系[包含两种情况:1.根本就不连通; 2.虽无直系但有共同祖先]
if(!checkIsConnect(h , p1 , p2)) {
return -1;
}
return GetCousin(h , p1 , p2) + " " + Math.abs(high.get(p1) - high.get(p2));
}
/*
* M代
* */
public static int GetCousin(HashMap<String , String> h , String p1 , String p2) {
//深的在右边的情况,交换一下。high左>high右
if(p1.compareTo(p2) < 0) {
String t = p1;
p1 = p2;
p2 = t;
}
//相差的深度
int sub = Math.abs(high.get(p1) - high.get(p2));
//较深的向上移动到和右子树相同高度
for(int i=0;i<sub;i++) {
p1 = h.get(p1);
}
int LCALen = 0;
while(true) {
if(h.get(p1) == h.get(p2)) {
break;
}
p1 = h.get(p1);
p2 = h.get(p2);
LCALen++;
}
return LCALen;
}
/*
* HashMap<儿子,父亲>
* */
public static void AddRelationShip(HashMap<String , String> h , String parent , String child) {
h.put(child , parent);
//给高度赋值
if(high.get(parent) == null) {
if(high.get(child) == null) {
//第一次构建该连通分量
high.put(parent , 1);
high.put(child , 0);
} else {
//在已有的连通分量[上面]加节点,高度+1
high.put(parent , high.get(child) + 1);
}
} else {
//在已有的连通分量[下面]加节点,高度-1
high.put(child , high.get(parent) - 1);
}
}
public static void main(String[] args) {
HashMap<String , String> h = new HashMap<>();
AddRelationShip(h , "Don" , "Fred" );
AddRelationShip(h , "Bill" , "John");
AddRelationShip(h , "Fred" , "Jack");
AddRelationShip(h , "Fred" , "Fran");
AddRelationShip(h , "Jack" , "Phil");
AddRelationShip(h , "Eric" , "Sun");
AddRelationShip(h , "Don" , "Bill" );
System.out.println(GetGeneration(h , "Don" , "Bill")); // 1
System.out.println(GetGeneration(h , "Sun" , "Jack")); // -1
System.out.println(GetGeneration(h , "John" , "Jack")); //1 0
System.out.println(GetGeneration(h , "Phil" , "Fred")); //2
System.out.println(GetGeneration(h , "Phil" , "John")); //1 1
}
}