之前我们使用了对象结点的方式表达了树的模型,在接下来图的的学习中,我们有非常多的不同的方式来表达图的模型,比如邻接表,邻接矩阵,十字链表,邻接多重表等等。为了方便学习图的思想,我们统一使用一种方式来对图进行表达,在以后遇到不同的表达方式时直接转换即可。
public class Graph{
public HashMap <Integer,Node>nodes;
public HashSet <Edge>edges;
public Graph (){
nodes = new HashMap<>();
edges = new HashSet<>();
}
}
public class Node{
int in;
int out;
int value;
public ArrayList<Node> nexts;
public ArrayList<Edge> edges;
public Node(int value){
this.value=value;
in=0;
out=0;
nexts=new ArrayList<>();
edges=new ArrayList<>();
}
}
public class Edge{
public int weight;
public Node from;
public Node to;
public Edge(int weight,Node from,Node to){
this.weight=weight;
this.from=from;
this.to=to;
}
}
图的宽度优先遍历
宽度优先遍历利用队列实现,从源结点依次按宽度进队列,然后弹出;每弹出一个点,把该点所有没进过队列的邻接点放入队列,不断往下直到队列空了
public static void bfs(Node node){
if(node==null) return;
Queue<Node> queue=new LinkedList<>();
HashSet<Node> Set=new HashSet<>();
queue.add(node);
set.add(node);
while(!queue.isEmpty()){
Node cur=queue.poll();
sout(cur.value);
for(Node next:cur.nexts){
if(!set.contains(nexts)){
set.add(next);
queue.add(next);}}}}
图的深度优先遍历
利用stack实现。从原点开始,把结点按照深度放入栈,然后弹出;每弹出一个点把该点下一个未进栈的邻接点入栈,往下直到栈空。
public static void dfs(Node node){
if(node==null) return;
Stack<Node> stack = new Stack<>();
HashSet<Node> set = new HashSet<>();
stack.add(node);
set.add(node);
sout(node.value);
while(!stack.isEmpty()){
Node cur=stack.pop();
for(Node next:cur.nexts){
if(!set.contains(next)){
stack.push(cur);
stack.push(next);
set.add(next);
sout(next.value);
break;
}
}
}
}
拓扑排序
在一个有向图中,首先弹出没有入度的点,并减去该点对图的影响,再弹出下一个没有入度的点,循环往复。
public static List<Node> sortedToplogy(Graph graph){
HashMap<Node,Integer> inMap=new HashMap<>();//某个结点的剩余入读
Queue<Node> zeroInQueue = new LinkedList<>();//入度为零才能进这个队
for(Node node:graph.nodes.values()){//将原始图数据存进inMap,同时让in=0的直接入队
inMap.put(node,node.in);
if(node.in==0)zetoInQueue.add(node);
}
List<Node> result=new ArrayList<>();
while(!zeroInQueue.isEmpty()){
Node cur = zeroInQueue.poll();
result.add(cur);
for(Node next:cur.nexts){
inMap.put(next,inMap.get(next)-1);
if(inMap.get(next)==0)zeroInQueue.add(next)
}
}
return result;
}

被折叠的 条评论
为什么被折叠?



