(Java)算法基础6:图/贪心算法(带模板上考场,模板一定滚瓜烂熟解决考场订制)

本文详细介绍了如何利用Java处理图算法,包括图的描述、点与边的表示、邻接表和邻接矩阵等数据结构。强调通过创建自定义模板来统一处理不同图的算法,如DFS、BFS、拓扑排序、Kruskal和Prim算法以及Dijkstra算法。文章还提供了这些算法的实现思路和关键代码片段。
摘要由CSDN通过智能技术生成

在这里插入图片描述
图由点集和边集构成。
有向图有箭头如下下图,无向图无箭头如下图
在这里插入图片描述
在这里插入图片描述
邻接表,如下图,记录ABCD的直接邻居。
这种结构可以表达所有图,比如有权值的图,如下下图

在这里插入图片描述

在这里插入图片描述

邻接矩阵法:用一个矩阵来表达上图(有向图,无向图都能表示)

在这里插入图片描述
图的题出现,难点在于已经会的算法还要重新实现一遍,因为图的实现方式太多了,但是突然换了一种图表达的方式,coding要变,

解决方法:把图按照自己最爱表达的方式实现所有的算法,作为自己以后遇到所有图问题的模板。

如下图,系统给出一个图,直接套自己实现的那个图的模板

图的表达方式太多了,比如邻接矩阵,邻接表这些。

对于题目给出的图的表达方式,自己只需要写一个两种结构的转化,就不用再重新写一遍算法了,即每次写图的题目的时候写一个接口,把它给的图结构变成自己最喜欢的那种图结构(自己喜欢的结构,平时已经用它的实现了所有的算法了),这里只用再求一个结果
在这里插入图片描述

图描述

package class06;

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

public class Graph {
   //图
	public HashMap<Integer,Node> nodes;//点集,
	//Integer表示key,Node表示实际的点
	public HashSet<Edge> edges;//边集

	public Graph() {
   
		nodes = new HashMap<>();
		edges = new HashSet<>();
	}
}

在这里插入图片描述

点描述

package class06;

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<>();
	}
}

在这里插入图片描述
A有0个入度,2个出度
B的入度1,出度1
C的入度2,出度0
参考下图
参考下图,A的nexts是B和C,B的nexts是C,nexts关注的是发散出去的边直接相邻的点有哪些。public ArrayList<Node> nexts;

C没哟nexts
在这里插入图片描述
在这里插入图片描述
参考下图:public ArrayList<Edge> edges;//属于我的边有哪些
属于A的边是下图蓝色,属于B的边是下图红色,没有边属于C
在这里插入图片描述

边描述

在这里插入图片描述

package class06;
//这里表达的是有向边,无向边不用管,无向边就相当于两条有向边拼的
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;
	}

}

接口(将用户给的千奇百怪的东西转为自己所熟悉的数据结构)

在这里插入图片描述
在这里插入图片描述
下述code转换上述结构为熟悉结构

package class06;

public class GraphGenerator {

	public static Graph createGraph(Integer[][] matrix) {
		Graph graph = new Graph();
		for (int i = 0; i < matrix.length; i++) {
		//matrix[0][0],边的权值
		//matrix[0][1],Node from
		//matrix[0][2],Node to
		
			Integer weight = matrix[i][0];
			Integer from = matrix[i][1];
			Integer to = matrix[i][2];
			//上述三行代码换了下顺序,理解意思。就是拿到form,to和权值。
			if (!graph.nodes.containsKey(from)) {/
			/如果此时的from城市没出现过
			//graph里面的nodes是一章HashMap,记录key和对应的Node
			//所以可以通过查询from这个key是否存在来判断Node from是否存在
				graph.nodes.put(from, new Node(from));//在图的点集中把这个城市新建出来,from这个点加进图里去了。
				//new Node(from)先初始化,调用class Node构造函数
			}
			if (!graph.nodes.containsKey(to)) {//同理to这个城市一样的操作
				graph.nodes.put(to, new Node(to));
			}
			
			Node fromNode = graph.nodes.get(from);//在点集里面,把from这个实际的点给拿出来
			Node toNode = graph.nodes.get(to);//在点集里面,把fto这个实际的点给拿出来
			Edge newEdge = new Edge(weight, fromNode, toNode);//根据上述的fromNode和toNode建立新的边

		//接下来按照class Node里需要的参数,取得对应value
			fromNode.nexts.add(toNode);
			fromNode.out++;
			toNode.in++;
			fromNode.edges.add(newEdge);//新建的边是属于fromNode的edges里,即其拥有的边里
			graph.edges.add(newEdge);//newedge放入边集
		}
		return graph;
	}

}

比如将下图这种用户给出的数据结构转为自己熟悉的

图的DFS和BFS

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值