图结构题目


图结构题目


图结构通用结构类

图:

package Graph;

import java.util.HashMap;
import java.util.HashSet;

public class Graph {

    public HashMap nodeHashMap;
    public HashSet edgesHashSet;
    
    public Graph(){
        nodeHashMap = new HashMap();
        edgesHashSet = new HashSet();
    }

}

图结点:

package Graph;

import java.util.ArrayList;

public class GraphNode {

    public int value;
    public int in;
    public int out;
    public ArrayList next;
    public ArrayList edges;

    public  GraphNode(int value){
        this.value = value;
        this.in = 0;
        this.out = 0;
        this.next = new ArrayList();
        this.edges = new ArrayList();
    }
}

边:

package Graph;

public class GraphEdges {

    public int weight; //权重
    public GraphNode in;
    public GraphNode from;

    public GraphEdges(int weiht, GraphNode from, GraphNode to){
        this.weight = weiht;
        this.in = to;
        this.from = from;
    }
}

生成图:

主函数:

package Graph;

import java.util.*;

public class GraphMain {

    public static void main(String[] args){

        //生成图
        int[][] arr = {{0,1,1},{1,0,2},{1,4,4},{4,1,3},{4,2,6},{2,4,5},{0,2,7},{2,0,8},{0,3,9},{3,0,10}}; //无向图
//        int[][] arr = {{0,1,1},{2,0,1},{2,4,1},{0,3,1},{1,4,1}};  //有向图
        GraphPractice graphPractice = new GraphPractice();
        Graph graph = graphPractice.createGraph(arr);
}

实现类:

package Graph;

import java.util.*;

public class GraphPractice {

    /**
     * 生成图
     * */
    public Graph createGraph(int[][] arr){
        Graph graph = new Graph();
        for(int i=0; i

题目一:宽度优先遍历和深度优先遍历

主函数类:

package Graph;

import java.util.*;

public class GraphMain {

    public static void main(String[] args){

        //生成图
        int[][] arr = {{0,1,1},{1,0,2},{1,4,4},{4,1,3},{4,2,6},{2,4,5},{0,2,7},{2,0,8},{0,3,9},{3,0,10}}; //无向图
//        int[][] arr = {{0,1,1},{2,0,1},{2,4,1},{0,3,1},{1,4,1}};  //有向图
        GraphPractice graphPractice = new GraphPractice();
        Graph graph = graphPractice.createGraph(arr);
        
         /**
         * 宽度优先遍历
         * */
        System.out.print("宽度优先遍历:");
        graphPractice.bfs(graph.nodeHashMap.get(1));
        System.out.println();

        /**
         * 深度优先遍历
         * */
        System.out.print("深度优先遍历:");
        graphPractice.dfs(graph.nodeHashMap.get(1));
        System.out.println();
}

实现类:

package Graph;

import java.util.*;

public class GraphPractice {

   /**
     * 宽度优先遍历
     * */
    public void bfs(GraphNode graphNode){
        if (graphNode == null) return;
        Queue queue = new LinkedList();
        HashSet set = new HashSet();
        ((LinkedList) queue).add(graphNode);
        set.add(graphNode);
        while (!queue.isEmpty()){
            GraphNode node = queue.poll();
            System.out.print(node.value+" ");  //处理区
            for(GraphNode nodes: node.next){
                if(!set.contains(nodes)){
                    ((LinkedList) queue).add(nodes);
                    set.add(nodes);
                }
            }
        }
    }

    /**
     * 深度优先遍历
     * */
    public void  dfs(GraphNode node){
        if(node == null) return;
        Stack stack = new Stack();
        HashSet set = new HashSet();
        stack.push(node);
        set.add(node);
        System.out.print(node.value+" ");
        while (!stack.isEmpty()){
            GraphNode tmp = stack.pop();
            for(GraphNode nodes:tmp.next){
                if(!set.contains(nodes)){
                    stack.push(tmp); //重新押回去,防止有结点遗漏
                    stack.push(nodes);
                    set.add(nodes);
                    System.out.print(nodes.value+" ");  //处理区
                    break;
                }
            }
        }
    }
}

题目二: 拓扑排序

主函数类:

package Graph;

import java.util.*;

public class GraphMain {

    public static void main(String[] args){

        //生成图
        int[][] arr = {{0,1,1},{1,0,2},{1,4,4},{4,1,3},{4,2,6},{2,4,5},{0,2,7},{2,0,8},{0,3,9},{3,0,10}}; //无向图
//        int[][] arr = {{0,1,1},{2,0,1},{2,4,1},{0,3,1},{1,4,1}};  //有向图
        GraphPractice graphPractice = new GraphPractice();
        Graph graph = graphPractice.createGraph(arr);
        
         /**
         * 拓扑排序
         * */
        List result = graphPractice.sortedTopology(graph);
        System.out.print("拓扑排序顺序:");
        for(GraphNode node:result) System.out.print(node.value+" ");
}

实现类:

package Graph;

import java.util.*;

public class GraphPractice {

   /**
     * 拓扑排序
     * 从入度为0的结点开始遍历,依次遍历入度为0的结点
     * */
    public List sortedTopology(Graph graph){
        HashMap map = new HashMap(); //value: 结点的入度数
        //入度为0的结点才能进队列
        Queue queue = new LinkedList<>();
        for(GraphNode node:graph.nodeHashMap.values()){
            map.put(node,node.in);
            if(node.in == 0) ((LinkedList) queue).add(node);
        }
        List result = new ArrayList();
        while (!queue.isEmpty()){
            GraphNode cur = queue.poll();
            result.add(cur);
            for(GraphNode next:cur.next){
                map.put(next,map.get(next)-1);
                if(map.get(next) == 0) ((LinkedList) queue).add(next);
            }
        }
        return result;
    }
}

题目三:最小生成树

package Graph;

import java.util.*;

public class GraphMain {

    public static void main(String[] args){

        //生成图
        int[][] arr = {{0,1,1},{1,0,2},{1,4,4},{4,1,3},{4,2,6},{2,4,5},{0,2,7},{2,0,8},{0,3,9},{3,0,10}}; //无向图
//        int[][] arr = {{0,1,1},{2,0,1},{2,4,1},{0,3,1},{1,4,1}};  //有向图
        GraphPractice graphPractice = new GraphPractice();
        Graph graph = graphPractice.createGraph(arr);
        
         /**
         * 生成最小生成树
         * */
        //k算法
        Set kResult = graphPractice.kruskalMST(graph);
        System.out.print("完成");

        //p算法
        Set pResult = graphPractice.primMST(graph);
        System.out.print("完成");
}

自定义边的比较器:

package Graph;

import java.util.Comparator;

//自定义边的比较器
public class EdgeComparator implements Comparator {
    @Override
    public int compare(GraphEdges o1, GraphEdges o2) {
        return o1.weight-o2.weight;
    }
}

自定义类并查集

package Graph;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

//类并查集
public class MySets {
    public HashMap> sets;

    public MySets(List list){
        sets = new HashMap>();
        for (GraphNode node:list){
            List newList = new LinkedList();
            newList.add(node);
            sets.put(node,newList);
        }
    }

    //检查是否为同一个集合
    public boolean isSameSet(GraphNode fromNode,GraphNode toNode){
        List fromList = sets.get(fromNode);
        List toList = sets.get(toNode);
        return fromList == toList;
    }

    //合并为同一个集合
    public void union(GraphNode fromNode,GraphNode toNode){
        List fromList = sets.get(fromNode);
        List toList = sets.get(toNode);
        for(GraphNode node:toList) {
            fromList.add(node);
            sets.put(node,fromList);
        }

    }

}

实现类:

package Graph;

import java.util.*;

public class GraphPractice {

    /**
     * k算法 最小生成树
     * 通过查看是否在同于一个集合里面
     * 从边的角度出发:获取最小的边,确认边俩端的结点是否再同一个集合,如果不在,就合在一起,在就跳过
     * 即先挑边再挑点
     * */
    //k算法实现最小生成树
    public Set kruskalMST(Graph graph){
        LinkedList nodeList =new LinkedList();
        for(GraphNode node : graph.nodeHashMap.values()) nodeList.add(node);
        MySets sets = new MySets(nodeList);
        PriorityQueue queue = new PriorityQueue(new EdgeComparator());
        for(GraphEdges edgs:graph.edgesHashSet){
            queue.add(edgs);
        }
        Set result = new HashSet();
        //通过确定是否再同一个集合确定是否能组成一个环
        while (!queue.isEmpty()){
            GraphEdges edges = queue.poll();
            if(!sets.isSameSet(edges.from,edges.in)){
                result.add(edges);
                sets.union(edges.from,edges.in);
            }
        }
        return result;
    }


    /**
     * p算法 生成最小生成树
     * 先挑点,再挑边
     * 从结点的所有边中,选择权重最小的点
     * */
    public Set primMST(Graph graph){
        PriorityQueue queue = new PriorityQueue(new EdgeComparator()); //存放可用于选择的边
        HashSet set = new HashSet();
        Set edgesSet = new HashSet();
        for(GraphNode node : graph.nodeHashMap.values()){ //for循环防止有森林的情况出现,即有没联通的俩片点
            if(!set.contains(node)){
                set.add(node);
                for(GraphEdges edges: node.edges) queue.add(edges);
                while (!queue.isEmpty()){
                    GraphEdges edges = queue.poll(); //比较器处理后,弹出来的第一条线一定是权重最小的那条
                    GraphNode toNode = edges.in;
                    if(!set.contains(toNode)){
                        set.add(toNode);
                        edgesSet.add(edges);
                        for(GraphEdges edges1:toNode.edges) queue.add(edges1);
                    }
                }
            }
        }
        return edgesSet;
    }
}