这里的代码参考了很多别人的代码和文章。。
今天师兄做笔试题,我也跟着看,碰到了一个要构建有向图并判断节点是否有环的题。
另一位师兄说这个题可以用并查集做,并且做出来了,我用并查集试了试做不出来。。
我觉得这题大概是要用有向图做,考察有向图的构建及寻找有向环
但是我只会对着书本抄代码构建有向图,不会寻找环,就尝试了一下用前不久做爬虫用到的广度遍历来寻找有向环。。
import java.util.*;
public class test
{
public static void main(String[] args)
{
UF uf = new UF();
//构建有向图
uf.AddDependency(1, 2);
uf.AddDependency(2, 4);
uf.AddDependency(4, 1);
uf.AddDependency(1, 6);
uf.AddDependency(6, 5);
uf.AddDependency(5, 7);
uf.AddDependency(4, 7);
boolean isCycle;
isCycle = uf.MouldelsCycularDependency(7); //判断对应节点是否有环
System.out.println(isCycle);
}
}
class UF
{
final int N = 10; //节点个数
//private static int E;
static Stack<Integer>[] adj;
public UF() //创建一个N个节点但没有边的图
{
adj = (Stack<Integer>[]) new Stack[N];
for(int n = 0; n < N;n++)
{
adj[n] = new Stack<Integer>();
}
}
public static void addEdge(int v,int w) //加边,v朝向w
{
adj[v].add(w);
}
public static Stack<Integer> adj(int v)
{
return adj[v];
}
public void clear()
{
adj = (Stack<Integer>[]) new Stack[N];
for(int n = 0; n < N;n++)
{
adj[n] = new Stack<Integer>();
}
}
public static void AddDependency(int Moduleld, int DependModuleld) //往图里加边
{
int v = Moduleld;
int w = DependModuleld;
addEdge(v,w);
}
public static boolean MouldelsCycularDependency(int Moduleld) //判断是否有环
{
int v = Moduleld;
HashMap<Integer,Boolean> oldMap = new HashMap<Integer,Boolean>();
for(int i: adj(v))
{
oldMap.put(i, false);
}
oldMap = reDo(oldMap,v);
if(oldMap.containsKey(v))
{
return true;
}
return false;
}
/**
* 广度优先遍历。递归,但是当N过大会StackOverFlow
* @param oldMap
* @param v 判断的节点
* @return
*/
public static HashMap<Integer,Boolean> reDo(HashMap<Integer,Boolean> oldMap,int v)
{
//定义newMap
HashMap<Integer,Boolean> newMap = new HashMap<Integer,Boolean>();
for(Map.Entry<Integer, Boolean> k : oldMap.entrySet())
{
if(k.getValue() == false)
{
for(int i: adj(k.getKey()))
{
if(i == v)
{
oldMap.put(i, false);
return oldMap;
}
if(!oldMap.containsKey(i))
{
newMap.put(i, false);
}
}
oldMap.replace(k.getKey(),false, true);
}
}
//有新节点,继续遍历
if (!newMap.isEmpty())
{
oldMap.putAll(newMap);
oldMap.putAll(reDo(oldMap,v));
}
return oldMap;
}
}
有一个致命的缺点,题给的节点数目超多,上面代码进行递归的时候八成会StackOverflow。。
扫描二维码关注公众号,回复:
1981632 查看本文章
但还是很有成就感的,思考了一晚上至少把最基本功能实现了。。