本文已参与「新人创作礼」活动,一起开启掘金创作之路。
图的常用概念
无向图顶点之间没有任何方向比如可以a-b也可以b-a 有向图有固定的链接方向就是有向图 带权图边带有权值的图也叫网
邻接矩阵 用二维数组表示0代表不链接 1代表有链接
用邻居接矩阵可能会造成空间的浪费
邻接表 他由数组加链表组成
完整代码展示
package name;
import java.math.BigInteger;
import java.util.*;
public class lanqiao {
private ArrayList<String>arr;//定义顶点集合也就是他的名字
private int [][]edgs;//邻接矩阵
private int numberof;//表示多少条边 个数数目
public static void main(String[] args) {
//测试图
int n=5;//节点的个数
String s1[]= {"A","B","C","D","E"};
//创建图对象
lanqiao graph = new lanqiao(n);
//循环添加顶点
for(String value:s1) {
graph.index(value);//添加值顶点
}
//添加边如果不添加边数据是全0的
// A-B A-C B-C B-D B-E
graph.insetag(0, 1, 1);//ab
graph.insetag(0, 2, 1);//ac
graph.insetag(1, 2, 1);//bc
graph.insetag(1, 3, 1);//bd
graph.insetag(1, 4, 1);//be
//显示链接矩阵
graph.showGret();
System.out.println();
}
//写一个构造器
public lanqiao(int n) {
//初始化矩阵和边
edgs=new int [n][n];
arr=new ArrayList<String>(n);
numberof=0;//他的边默认为0
}
//插入节点也就是插入顶点
public void index(String s1) {//插入顶点传入的就是顶点的字符串
arr.add(s1);//插入节点
}
//图中常用方法
//返回图结点的个数
public int getNumber() {
return arr.size();//节点个数也就是数组长度
}
//得到边的数目
public int getNumberof() {
return numberof;
}
//返回节点i(下标)对应的数据 0返回A 1返回B 2 返回 C根据节点的添加顺序有关
public String getValue(int i) {
return arr.get(i);
}
//返回v1和v2的权
public int getWeight(int v1,int v2) {
return edgs[v1][v2];//这个方法返回权值
}
public void showGret() {//返回图的这个矩阵
for(int [] link:edgs) {
System.out.println(Arrays.toString(link));
}
}
//添加边通过矩阵来描述他们的边
//权值weigth 权值就是边对应的值要么是1要么是0 默认是
public void insetag(int v1,int v2,int weigth) {
//v1代表数组里面的A-B之间A和B的链接是0还是1
//v2表示指定里面的第几个元素比如是C那么v2就是3
//权值表示他们是关联的0或1
edgs[v1][v2]=weigth;
edgs[v2][v1]=weigth;//因为是无向图所以反过来一编
numberof++;//边+1
}
}
图论dfs 1.先找到第一个初始节点,然后把经历过的节点都标记已访问 2.查找节点的第一个邻接节点 3.如果w节点存在执行4 如果代码不存在返回最初的节点继续往下走 4.如果w节点未被访问那么对w进行深度优先遍历可以把w当作另一个v然后进行步骤重新123 5.查找节点w的邻接节点的下一个节点转到步骤3
package Graph;
import java.nio.Buffer;
import java.util.*;
public class Graph {
private ArrayList<String> arr;// 定义顶点集合也就是他的名字
private int[][] edgs;// 邻接矩阵
private int numberof;// 表示多少条边 个数数目
private boolean[] isVisti;
public static void main(String[] args) {
// 测试图
int n = 5;// 节点的个数
String s1[] = { "A", "B", "C", "D", "E" };
// 创建图对象
Graph graph = new Graph(n);
// 循环添加顶点
for (String value : s1) {
graph.index(value);// 添加值顶点
}
// 添加边如果不添加边数据是全0的
// A-B A-C B-C B-D B-E
graph.insetag(0, 1, 1);// ab
graph.insetag(0, 2, 1);// ac
graph.insetag(1, 2, 1);// bc
graph.insetag(1, 3, 1);// bd
graph.insetag(1, 4, 1);// be
// 显示链接矩阵
graph.showGret();
System.out.println();
graph.dfs();
}
// 写一个构造器
public Graph(int n) {
// 初始化矩阵和边
isVisti = new boolean[5];
edgs = new int[n][n];
arr = new ArrayList<String>(n);
numberof = 0;// 他的边默认为0
}
// 得到第一个邻接结点的下标
public int getFir(int index) {
for (int j = 0; j < arr.size(); j++) {
if (edgs[index][j] > 0) {
return j;
// 如果他的旁边有节点就返回节点
// 否则返回-1
}
}
return -1;
}
// 根据前一个邻接节点的下标获取下一个邻接节点
public int getNext(int v1, int v2) {
for (int j = v2 + 1; j < arr.size(); j++) {
if (edgs[v1][j] > 0) {
return j;
}
}
// v1 是当前节点 v1是邻接节点
return -1;
}
// dfs
// i第一次就是0
public void dfs(boolean[] isVisited, int i) {
System.out.println(getValue(i) + ">");
// 把访问过的节点设置为已经访问过了
isVisited[i] = true;
int w = getFir(i);// 查找节点i的第一个邻接节点
while (w != -1) {
if (!isVisited[w]) {// 判断他是否被访问过
dfs(isVisited, w);
}
// 如果w节点已经被访问过
w = getNext(i, w);// i正在访问的节点
}
}
// dfs 进行重载遍历所有的节点进入dfs
public void dfs() {
// 遍历所有的节点,进行dfs回溯
for (int i = 0; i < getNumber(); i++) {
if (!isVisti[i]) {
dfs(isVisti, i);
}
}
}
// 插入节点也就是插入顶点
public void index(String s1) {// 插入顶点传入的就是顶点的字符串
arr.add(s1);// 插入节点
}
// 图中常用方法
// 返回图结点的个数
public int getNumber() {
return arr.size();// 节点个数也就是数组长度
}
// 得到边的数目
public int getNumberof() {
return numberof;
}
// 返回节点i(下标)对应的数据 0返回A 1返回B 2 返回 C根据节点的添加顺序有关
public String getValue(int i) {
return arr.get(i);
}
// 返回v1和v2的权
public int getWeight(int v1, int v2) {
return edgs[v1][v2];// 这个方法返回权值
}
public void showGret() {// 返回图的这个矩阵
for (int[] link : edgs) {
System.out.println(Arrays.toString(link));
}
}
// 添加边通过矩阵来描述他们的边
// 权值weigth 权值就是边对应的值要么是1要么是0 默认是
public void insetag(int v1, int v2, int weigth) {
// v1代表数组里面的A-B之间A和B的链接是0还是1
// v2表示指定里面的第几个元素比如是C那么v2就是3
// 权值表示他们是关联的0或1
edgs[v1][v2] = weigth;
edgs[v2][v1] = weigth;// 因为是无向图所以反过来一编
numberof++;// 边+1
}
}