class6 图(左程云左神算法 初级笔记 2018)

class6

  • 图的存储方式
    1)邻接表
    2)邻接矩阵
package com.godzuo.java;

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

/**
 * @author quanquan
 * @create 2020-05-03-20:40
 */
public class Graph {
    public HashMap<Integer,Node> nodes;
    public HashSet<Edge> edges;

    public Graph() {
        nodes = new HashMap<>();
        edges = new HashSet<>();
    }
}
package com.godzuo.java;

import java.util.ArrayList;

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<>();
	}
}
package com.godzuo.java;

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.godzuo.java;

/**
 * 生成图
 */
public class GraphGenerator {

	public static Graph createGraph(Integer[][] matrix) {
		Graph graph = new Graph();
		for (int i = 0; i < matrix.length; i++) {
			Integer weight = matrix[i][0];
			Integer from = matrix[i][1];
			Integer to = matrix[i][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;
	}

}
    • 广度(宽度)优先遍历

      1,利用队列实现

      2,从源节点开始依次按照宽度进队列,然后弹出

      3,每弹出一个点,把该节点所有没有进过队列的邻接点放入队列

      4,直到队列变空

    • 深度优先遍历

      1,利用栈实现

      2,从源节点开始把节点按照深度放入栈,然后弹出

      3,每弹出一个点,把该节点下一个没有进过栈的邻接点放入栈

      4,直到栈变空

package com.godzuo.java;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;

/**
 * @author quanquan
 * @create 2020-05-03-21:30
 */
public class BFS {
    public static void bfs(Node node){
        if (node == null){
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        HashSet<Node> map = new HashSet<>();
        queue.add(node);
        map.add(node);
        while (!queue.isEmpty()){
            Node cur = queue.poll();
            System.out.println(cur.value);
            for (Node next: cur.nexts){
                if(!map.contains(next)){
                    map.add(next);
                    queue.add(next);
                }
            }
        }
    }
    
}
package com.godzuo.java;

import java.util.HashSet;
import java.util.Set;
import java.util.Stack;

/**
 * @author quanquan
 * @create 2020-05-03-21:49
 */
public class DFS {
    
    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;
                }
            }
        }

    }
}
  • 拓扑排序算法(做到自己时,依赖条件都已做完)

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

package com.godzuo.java;

import java.util.*;


/**
 * @author quanquan
 * @create 2020-05-03-22:24
 */
public class TopologySort {

    // directed graph and no loop
    public static List<Node> sortedTopology(Graph graph){
        HashMap<Node, Integer> inMap = new HashMap<>();
        Queue<Node> zeroInQue = new LinkedList<>();
        for (Node node : graph.nodes.values()){ //遍历所有的点
            inMap.put(node, node.in);
            if (node.in == 0){
                zeroInQue.add(node);
            }
        }
        List<Node> result = new ArrayList<>();
        while (!zeroInQue.isEmpty()){
            Node cur = zeroInQue.poll();
            result.add(cur);
            for (Node next : cur.nexts){
                inMap.put(next,inMap.get(next)-1);
                if (inMap.get(next) == 0){
                    zeroInQue.add(next);
                }
            }
        }
        return result;
    }
}
  • 最小生成树算法(要求:无向图):kruskal算法 和 prim算法

    • kruskal算法:从小权重的边开始考察
    package com.godzuo.java;
    
    import java.util.Collection;
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.PriorityQueue;
    import java.util.Set;
    
    //undirected graph only
    public class Kruskal {
    
    	// Union-Find Set
    	public static class UnionFind {
    		private HashMap<Node, Node> fatherMap;
    		private HashMap<Node, Integer> rankMap;
    
    		public UnionFind() {
    			fatherMap = new HashMap<Node, Node>();
    			rankMap = new HashMap<Node, Integer>();
    		}
    
    		private Node findFather(Node n) {
    			Node father = fatherMap.get(n);
    			if (father != n) {
    				father = findFather(father);
    			}
    			fatherMap.put(n, father);
    			return father;
    		}
    
    		public void makeSets(Collection<Node> nodes) {
    			fatherMap.clear();
    			rankMap.clear();
    			for (Node node : nodes) {
    				fatherMap.put(node, node);
    				rankMap.put(node, 1);
    			}
    		}
    
    		public boolean isSameSet(Node a, Node b) {
    			return findFather(a) == findFather(b);
    		}
    
    		public void union(Node a, Node b) {
    			if (a == null || b == null) {
    				return;
    			}
    			Node aFather = findFather(a);
    			Node bFather = findFather(b);
    			if (aFather != bFather) {
    				int aFrank = rankMap.get(aFather);
    				int bFrank = rankMap.get(bFather);
    				if (aFrank <= bFrank) {
    					fatherMap.put(aFather, bFather);
    					rankMap.put(bFather, aFrank + bFrank);
    				} else {
    					fatherMap.put(bFather, aFather);
    					rankMap.put(aFather, aFrank + bFrank);
    				}
    			}
    		}
    	}
    
    	public static class EdgeComparator implements Comparator<Edge> {
    
    		@Override
    		public int compare(Edge o1, Edge o2) {
    			return o1.weight - o2.weight;
    		}
    
    	}
    
    	public static Set<Edge> kruskalMST(Graph graph) {
    		UnionFind unionFind = new UnionFind(); // 生成并查集
    		unionFind.makeSets(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 edge = priorityQueue.poll();
    			if (!unionFind.isSameSet(edge.from, edge.to)) {
    				result.add(edge);
    				unionFind.union(edge.from, edge.to);
    			}
    		}
    		return result;
    	}
    }
    • prim算法:按照点来考察
    package com.godzuo.java;
    
    import java.security.PublicKey;
    import java.util.*;
    
    /**
     * @author quanquan
     * @create 2020-05-03-23:37
     */
    public class Prim {
        public static class EdgeComparator implements Comparator<Edge> {
    
            @Override
            public int compare(Edge o1, Edge o2) {
                return o1.weight - o2.weight;
            }
    
        }
    
        public static Set<Edge> primMST(Graph graph) {
            PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(
                    new EdgeComparator());
            HashSet<Node> set = new HashSet<>();
            Set<Edge> result = new HashSet<>();
            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算法 适用范围:没有权值为负数的边
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值