图的遍历总结模板和最小生成树

图的遍历总结模板

图的存储方式

邻接表
邻接矩阵

图的模板代码

package com.itcast.Graphy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class tu1 {
    public  class Graph{
        //图是有点集和边集
        public HashMap<Integer, Node> nodes;
        public HashSet<Edge> edges;
        public  Graph(){
            nodes=new HashMap<>();
            edges=new HashSet<>();
        }
    }
    public  class Node{
        public  int value;
        public  int in;
        public  int out;
        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;
        }
    }
}

实例:

package com.itcast.Graphy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class tu2 {
    public   static  class Graph{
        //图是有点集和边集
        public HashMap<Integer, Node> nodes;
        public HashSet<Edge> edges;
        public  Graph(){
            nodes=new HashMap<>();
            edges=new HashSet<>();
        }
    }
    public   static class Node{
        public  int value;
        public  int in;
        public  int out;
        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   static 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 Graph creat(Integer [][] matrix){
        Graph graph= new Graph();
        for(int i=0;i<matrix.length;i++){
            Integer from=matrix[0][0];
            Integer to=matrix[0][1];
            Integer weight=matrix[0][2];
            if(!graph.nodes.containsKey(from)){
                graph.nodes.put(from,new Node(from));
            }
            if(!graph.nodes.containsKey(to)){
                graph.nodes.put(to,new Node(to));
            }
            Node fromNode=graph.nodes.get(from);
            Node toNode=graph.nodes.get(to);
            Edge newEdge=new Edge(weight,fromNode,toNode);
            fromNode.nexts.add(toNode);
            fromNode.out++;
            toNode.in++;
            fromNode.edges.add(newEdge);
            graph.edges.add(newEdge);
        }
        return  graph;
    }
}

宽度优先遍历

思想:

  • 利用队列实现
  • 从源节点开始按照宽度进队列,然后弹出
  • 每弹出一个点,把该节点所有没有进过队列的邻接点放入队列
  • 直到队列变空

代码

package com.itcast.Graphy;
import java.util.*;
public class bfs {
    public  class Node{
        public  int value;
        public  int in;
        public  int out;
        public ArrayList< Node> nexts;
        public  Node(int value){
            this.value=value;
            in=0;
            out=0;
            nexts=new ArrayList<>();
        }
    }
   
    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();
            System.out.println(cur.value);
            for(Node next:cur.nexts){
                if(!set.contains(next)){
                    set.add(next);
                    queue.add(next);
                }
            }
        }
    }
}

广度优先遍历

思想:

  • 利用栈实现
  • 从源节点开始把节点按照深度放入栈,然后弹出
  • 每弹出一个点,把该节点下一个没有进入过栈的邻接点放入栈
  • 直到栈变空
package com.itcast.Graphy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Stack;
public class dfs {
    public  class Node{
        public  int value;
        public  int in;
        public  int out;
        public ArrayList< Node> nexts;
        public  Node(int value){
            this.value=value;
            in=0;
            out=0;
            nexts=new ArrayList<>();
        }
    }
    
    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);
        System.out.println(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);
                    System.out.println(next.value);
                    break;
                }
            }
        }
    }
}

拓扑排序算法

适用范围:要求有向图,且有入度为的节点,且没有环

在这里插入图片描述
排序结果:A,B,C,D
找到入度为0的节点,然后排好序,删除该节点对其它节点的影响,

package com.itcast.Graphy;
import java.util.*;
public class TopLogSort {
    public  static  class Graph{
        public HashMap<Integer,Node>  nodes;
        public HashSet<Edge> edges;
        public  Graph(){
            nodes=new HashMap<Integer, Node>();
            edges=new HashSet<Edge>();
        }
    }
    public  static   class Node{
        public  int value;
        public  int in;
        public  int out;
        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<Edge>();
        }
    }
    public  static 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 List<Node> sort(Graph graph) {
        //key:某一个node
        //value:剩余的入度
        HashMap<Node, Integer> inMAP = new HashMap<>();
        //入度为0的节点才能进入队列
        Queue<Node> zeroqueue=new LinkedList<>();
        for(Node node:graph.nodes.values()){
            inMAP.put(node,node.in);
            if(node.in==0){
                zeroqueue.add(node);
            }
        }
        //拓扑排序结果,依次加入resul
        List<Node> result=new ArrayList<>();
        while(!zeroqueue.isEmpty()){
            Node cur=zeroqueue.poll();
            result.add(cur);
            for(Node next:cur.nexts){
                inMAP.put(next,inMAP.get(next)-1);
                if(inMAP.get(next)==0){
                    zeroqueue.add(next);
                }
            }
        }
        return  result;
    }
}

Kruskal

适用范围:要求无向图

最小生成树:
从最小的边开始考虑,如果加上没环,就要,有环就不要
在这里插入图片描述

package com.itcast.Graphy;
import java.util.*;
public class kruskal {
    public  class Graph{
        //图是有点集和边集
        public HashMap<Integer,  Node> nodes;
        public HashSet< Edge> edges;
        public  Graph(){
            nodes=new HashMap<>();
            edges=new HashSet<>();
        }
    }
    public  class Node{
        public  int value;
        public  int in;
        public  int out;
        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 class  Mysets{
        public HashMap<Node,List<Node>> setMap;
        public  Mysets(List<Node> nodes){
            for(Node cur:nodes){
                List<Node> set=new ArrayList<Node>();
                set.add(cur);
                setMap.put(cur,set);
            }
        }
        public  boolean ISame(Node from,Node to){
            List<Node> fromSet=setMap.get(from);
            List<Node> toSet=setMap.get(to);
            return  toSet==fromSet;//比较两个的内存地址,判断两个是不是同一个集合
        }
        public  void union(Node from,Node to){
            List<Node> fromSet=setMap.get(from);
            List<Node> toSet=setMap.get(to);
            for(Node toNode:toSet){
                fromSet.add(toNode);
                setMap.put(toNode,fromSet);
            }
        }
    }
    public static  class   Edgecomparator implements  Comparator<Edge>{
        @Override
        public int compare(Edge o1, Edge o2) {
            return  o1.weight-o2.weight;
        }
    }
    public  static Set<Edge> kruskalprocess(Graph graph){
        //伪码
        Mysets mysets=new Mysets();
        Mysets.Mysets(graph.nodes.values());
        PriorityQueue<Edge> priorityQueue=new PriorityQueue<>(new Edgecomparator());
        for(Edge edge:graph.edges){
            priorityQueue.add(edge);
        }
        Set<Edge> result=new HashSet<>();
        while(!priorityQueue.isEmpty()){
            Edge cur=priorityQueue.poll();
            //判断两个集合相同不,
            //合并
        }
    }
}

prim算法:

要求:无向图
在这里插入图片描述

package com.itcast.Graphy;
import java.util.*;
public class Prim {
    public  class Graph{
        //图是有点集和边集
        public HashMap<Integer,  Node> nodes;
        public HashSet< Edge> edges;
        public  Graph(){
            nodes=new HashMap<>();
            edges=new HashSet<>();
        }
    }
    public  class Node{
        public  int value;
        public  int in;
        public  int out;
        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  class   Edgecomparator implements Comparator< Edge> {
        @Override
        public int compare( Edge o1,  Edge o2) {
            return  o1.weight-o2.weight;
        }
    }
    public static Set<Edge> prim(Graph graph){
        //解锁的边进入小根堆
        PriorityQueue<Edge> priorityQueue=new PriorityQueue<>(new  Edgecomparator());
        HashSet<Node> set=new HashSet<>();
        Set<Edge> result=new HashSet<>();//依次挑选的边放入result
        for(Node node:graph.nodes.values()){
            if(!set.contains(node)){
                set.add(node);
                for(Edge edge:node.edges){
                    priorityQueue.add(edge);//由一个点解所有相连的边
                }
                while(!priorityQueue.isEmpty()){
                    Edge edge=priorityQueue.poll();//弹出解锁边中,最小的边
                    Node toNode=edge.to;//可能的一个新的点
                    if(!set.contains(toNode)){//不含有的时候就是新的点
                        set.add(toNode);
                        result.add(edge);
                        for(Edge nextedge:toNode.edges){
                            priorityQueue.add(nextedge);
                        }
                    }
                }
            }
        }
        return  result;
    }
}

Dijkstra算法

适用发范围:没有权值为负数的边
在这里插入图片描述

package com.itcast.Graphy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
public class Dijkstra {
    public static class Graph{
        //图是有点集和边集
        public HashMap<Integer,  Node> nodes;
        public HashSet< Edge> edges;
        public  Graph(){
            nodes=new HashMap<>();
            edges=new HashSet<>();
        }
    }
    public static class Node{
        public  int value;
        public  int in;
        public  int out;
        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 static 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 HashMap<Node,Integer> Dijkstra1(Node form){
        //从from出发到所有点的最短距离
        //key:从from出发到达可以
        //value:从form出发到达key的最小距离
        //如果表中没有T的记录,表示从form出发到达T的距离为正无穷
        HashMap<Node, Integer> distanceMap=new HashMap<>();
        distanceMap.put(form, 0);
        //已经求过距离的点,存在selectedNodes中,再也不碰
        HashSet<Node> selectedNodes=new HashSet<>();
        //遍历distanceMap,把除去selectedNodes中,所有距离最小的点取出来。
        Node miNode=getMinDistanceAndUnselectedNodes(distanceMap,selectedNodes);
        while(miNode!=null){
            int distance=distanceMap.get(miNode);
            for(Edge edge:miNode.edges){
                Node toNode=edge.to;
                //如果表中没有这个结点,就添加结点和距离
                //有,则更新结点最短距离
                if (!distanceMap.containsKey(toNode)) {
                    distanceMap.put(toNode, distance+edge.weight);
                }else {
                    distanceMap.put(toNode, Math.min(distanceMap.get(toNode), distance+edge.weight));
                }
            }
            selectedNodes.add(miNode);
            miNode=getMinDistanceAndUnselectedNodes(distanceMap, selectedNodes);
        }
        return distanceMap;
    }
    public static Node getMinDistanceAndUnselectedNodes(
            HashMap<Node, Integer>distanceMap,
            HashSet<Node>touchedNodes){//touchedNodes就是我们之前的selectedNodes
        Node miNode=null;
        int  mindistance=Integer.MAX_VALUE;
        for(Entry<Node, Integer> entry:distanceMap.entrySet()){
            Node node=entry.getKey();
            int distance=entry.getValue();
            if(!touchedNodes.contains(node)&&distance<mindistance){
                miNode=node;
                mindistance=distance;
            }
        }
        return miNode;
    }
    public static void main(String[] args) {
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值