版权声明:071623 https://blog.csdn.net/weixin_43584220/article/details/88802245
package cn.DataStructureAndAlgorithms01.Ravanla;
/**
*
* @author Ravanla
*在做图之前我们先要理解图里面的内容
* 点在图内,所以我们可以理解点是一个类(class),图是一个类,
* 图的方法是集合图内的所有点的方法点的方法是针对自己的
* 就像一个班有40名学生,每个学生都有自己的求平均分方法,这个班
* 也可以有自己的求平均分方法,但是这个平均分是全班的平均分而不是一个学生的
*
1.首先我们的图需要有转载点的数组和表示点与点关系的二维数组(邻接矩阵),他们的长度由图的构造函数决定
2.需要添加点方法(addVertex)
*A.图
* 1.把传来的点添加到转载点的数组
public class Graph {
private Vertex[] vertex;
private int index = 0;
public int[][] adjMat;
public MyStack stack = new MyStack(5);
public int currentIndex = 0;
public Graph(int size) {
vertex = new Vertex[size];
adjMat = new int[size][size];
}
public void addVertex(Vertex v) {
vertex[index++] = v;
}
3.然后用添加边的方法将两个点链接起来(addEdge)
*
* 1.遍历全转载点的数组(vertex[])找到传来的两个形参相应的下标
* 2.将邻接矩阵对应两个形参的下标设置为1,表示他们两个有关系,当然两个形参反过来也要设置为1
* 3.最后将自己和自己由关系的也设置为1
public void addEdge(String v1, String v2) {
int index1 = 0;
for(int i = 0; i < vertex.length; i++) {
if(vertex[i].getValue().equals(v1)) {
index1 = i;
}
}
int index2 = 0;
for(int i = 0; i < vertex.length; i++) {
if(vertex[i].getValue().equals(v2)) {
index2 = i;
}
}
for(int i = 0; i < vertex.length; i++) {
adjMat[i][i] = 1;
}
adjMat[index1][index2] = 1;
adjMat[index2][index1] = 1;
}
4.创建一个栈类,在Graph中设置一个栈对象
*
* 1.在这个对象中需要由栈数组,还有规定这个数组长度的变量maxSize(在构造函数中设置)
* 2.这个对象需要由压栈方法
* 3.出栈方法
* 4.判读是否为空方法
* 5.放回栈顶元素变量方法
package cn.DataStructureAndAlgorithms01.Ravanla;
public class MyStack {
public int[] stack =null;
// public int index = 0;
private int maxSize = 0;
private int top = -1;
public MyStack(int size) {
maxSize = size;
stack = new int[maxSize];
}
public void push(int i) {
if(top == maxSize - 1) {
throw new RuntimeException("push栈已满");
}
else {
stack[++top] = i;
}
}
public int pop() {
if(top == -1) {
throw new RuntimeException("pop栈为空");
}
else {
// int i = stack[top--];
// stack[top--] = 0;
return stack[top--];
}
}
public boolean isEmpty() {
return top == -1 ? true:false;
}
public int peek() {
return stack[top];
}
}
5.最后我们需要遍历图的方法(这里我用的是深度优先搜索Deep First Search,广度优先算法Breadth First Search就明天写)
* 1.首先我们把转载第一个的点设置为访问过
* 2.然后将其下标压入栈中
* 3.最后打印这个点的值
* 1.如果栈不为空,
* 2.接下来我们就从第二个点开始遍历全转载点的数组
* 1.如果这个点没有被访问且它在邻接矩阵中是1(有关系)
* 1.就像4开头的123那样 设置为访问过 下标压入栈 打印
* 2.再继续找下去
* 3.接下来就把刚才压入的栈的下标推出
* 4.然后判断栈是否为空,不空则将刚刚推出栈的下标的上一个元素赋值给当前下标
public void dfs() {
vertex[0].visited = true;
stack.push(0);
System.out.println(vertex[0].getValue());
out:while(!stack.isEmpty()) {
for(int i = currentIndex + 1; i < vertex.length; i++) {
if(vertex[i].visited == false
&& adjMat[currentIndex][i] == 1) {
vertex[i].visited = true;
stack.push(i);
System.out.println(vertex[i].getValue());
continue out;
}
}
stack.pop();
if(!stack.isEmpty()) {
currentIndex = stack.peek();
}
}
}
这是顶点(点)类
package cn.DataStructureAndAlgorithms01.Ravanla;
/**
*
* @author Ravanla
*vertex:顶点
*/
public class Vertex {
private String value;
public boolean visited = false;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Vertex(String value) {
super();
this.value = value;
}
@Override
public String toString() {
return "Vertex [value=" + value + "]";
}
}
这是测试图类
package cn.DataStructureAndAlgorithms01.Ravanla;
import java.util.Arrays;
public class TestGraph {
public static void main(String[] args) {
Graph g = new Graph(5);
Vertex v1 = new Vertex("A");
Vertex v2 = new Vertex("B");
Vertex v3 = new Vertex("E");
Vertex v4 = new Vertex("D");
Vertex v5 = new Vertex("C");
g.addVertex(v1);
g.addVertex(v2);
g.addVertex(v3);
g.addVertex(v4);
g.addVertex(v5);
g.addEdge("A", "B");
g.addEdge("C", "B");
g.addEdge("D", "B");
g.addEdge("E", "B");
g.addEdge("A", "C");
// for(int a:g.adjMat) {
for(int[] a:g.adjMat) {
System.out.println(Arrays.toString(a));
}
System.out.println("=========");
g.dfs();
}
}
// A B E D C
/*A*/[1, 1, 0, 0, 1]
/*B*/[1, 1, 1, 1, 1]
/*E*/[0, 1, 1, 0, 0]
/*D*/[0, 1, 0, 1, 0]
/*C*/[1, 1, 0, 0, 1]
=========
A
B
C
E
D