图的一些知识的整理
import java.util.LinkedList;
/**
* 图的创建-->邻接矩阵
*
* */
public class Graph {
private int vertexSize; //顶点数量
private int[] vertexs; // 结点数组(存储每一个结点的编号)
private int[][] matrix; // 邻接矩阵
private final int MAX_WEIGHT = 1000; // 不能到达的路的权值
private boolean[] isVisited;
public Graph(int vertexSize){
this.vertexSize = vertexSize;
this.matrix = new int[vertexSize][vertexSize];
this.vertexs = new int[vertexSize];
for (int i = 0;i<vertexSize;i++){
vertexs[i] = i; // 表示V0--V4
}
isVisited = new boolean[vertexSize];
}
/**
*
* 获得某结点的出度
* */
public int getOutDegree(int index){
int degree = 0;
for (int j=0;j<this.matrix[index].length;j++){
int wight = this.matrix[index][j];
if (wight>0 && wight < this.MAX_WEIGHT){
degree++;
}
}
return degree;
}
/**
*
* 获取两个顶点之间的权值
*
* */
public int getWeigth(int v1,int v2){
int weight = this.matrix[v1][v2];
return ( weight==0 )? (0) :(weight<this.MAX_WEIGHT ? weight : -1);
}
/**
* 获取第一个邻接点
* */
public int getFirstNeifhbor(int index){
for (int j=0;j<this.matrix[index].length;j++){
if (matrix[index][j]> 0 && matrix[index][j]<MAX_WEIGHT){
return j;
}
}
return -1;
}
/**
* 获取此结点相对于(某结点)的下一个邻接点
* @param v1 代表要查邻接点的的结点
*
* @param v2 代表相对于v1的邻接点
* */
public int getNextNeighbor(int v1,int v2){
for (int j = v2+1;j<matrix[v1].length;j++){
if (matrix[v1][j]> 0 && matrix[v1][j]<MAX_WEIGHT){
return j;
}
}
return -1;
}
/**
* 图的深度优先遍历
* */
private void depthFirstSearch(int index){
// 标记此节点被访问
isVisited[index] = true;
// 得到它的第一个邻接点
int w = this.getFirstNeifhbor(index);
//如果有邻接点进入循环
while(w!=-1){
//查看这个邻接点是否被访问过了
if(!isVisited[w]){
System.out.println("访问到了"+w+"结点");
// 遍历邻接结点的邻接结点
depthFirstSearch(w);
}
w = this.getNextNeighbor(index,w); // 第一个相对于w的邻接结点
}
}
/**
* 防止有些顶点达不到
*这样做的目的是强制遍历所有结点
*
* */
public void depthFirstSearch(){
isVisited = new boolean[vertexSize];
for (int i=0;i<vertexSize;i++){
if(!isVisited[i]){
System.out.println("访问第"+i+"结点");
depthFirstSearch(i);
}
}
//遍历完成之后将标记全部初始化
isVisited = new boolean[vertexSize];
}
/**
*
* 图的广度优先遍历
* */
private void broadFirstSearch(int index){
int u,w;
LinkedList<Integer> queue = new LinkedList<>();
System.out.println("访问到第"+index+"个结点");
isVisited[index] = true;
queue.add(index);
while(!queue.isEmpty()){
u = queue.removeFirst();
w = getFirstNeifhbor(u);
while (w!=-1){
if(!isVisited[w]){
System.out.println("访问到第"+ w +"结点");
queue.add(w);
isVisited[w] = true;
}
w = getNextNeighbor(u,w);
}
}
}
public void broadFirstSearch(){
isVisited = new boolean[vertexSize];
LinkedList<Integer> queue = new LinkedList<>();
for (int i=0;i<vertexSize;i++){
if (!isVisited[i]){
broadFirstSearch(i);
}
}
}
/**
* 普利姆算法
* */
public void prim(){
/**
* 存放当前所能到达的最小权值,因为要遍历完整个二维数组,所以可能某些值是虚拟的
最小权值,之后可能会更新,因为当前只能到达这些顶点了嘛
* lowcoat 的解释
* */
int[] lowcost = new int[vertexSize];
int[] adjvex = new int[vertexSize]; // 存放最小权值的顶点,最小权值顶点为:最小生成树的顶点
// min 表示最短的路径长度
int min,minId,sum = 0;
// 先随机选择一个顶点作为初始顶点
//默认我们选V0为第一个最小权值顶点
// 因为你最终要选完所有的顶点,所以你选的顶点不影响全局
// 然后让那个lowcost为你所选顶点能到达的所有边的权值
// 此处要注意: i 是从1开始赋值的,因为你已经把零选过了
for (int i = 1;i<vertexSize;i++){
lowcost[i] = matrix[0][i];
}
for (int i = 1;i<vertexSize;i++){
min = MAX_WEIGHT;
minId = 0;
for (int j = 1;j<vertexSize;j++){
// 选出lowcost中最小的值,就为要选的路了
if(lowcost[j] < min && lowcost[j]>0){
min = lowcost[j];
minId = j; // 记录当先最小顶点的ID
}
}
System.out.println("顶点"+adjvex[minId]+"权值"+min);
sum += min;
lowcost[minId] = 0; // lowcost=0 表明你已经选了这个顶点作为当先最小的权值顶点
for (int j =1; j<vertexSize;j++){
//从你选的这个顶点开始寻找可到达的路
if (lowcost[j]!=0 && matrix[minId][j] < lowcost[j]){
// 如果这些路的权值有比我们lowcost中小的,则更新啊lowcost的值
// 注意就当你更新了,也不代表这个值就是最小的路径,所以还要进行下一次的循环,遍历(上面的代码)
// 选出最小的出来
lowcost[j] = matrix[minId][j]; // 更新
adjvex[j] = minId; //记录最小权值顶点
}
}
}
System.out.println(sum);
}
public int[] getVertexs() {
return vertexs;
}
public void setVertexs(int[] vertexs) {
this.vertexs = vertexs;
}
public static void main(String[] args){
// Graph graph = new Graph(5);
/* int[] a0 = {0,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,6};
int[] a1 = {9,0,3,graph.MAX_WEIGHT,graph.MAX_WEIGHT};
int[] a2 = {2,graph.MAX_WEIGHT,0,5,graph.MAX_WEIGHT};
int[] a3 = {graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,0,1};
int[] a4 = {graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,0};
*/
Graph graph = new Graph(9);
int[] a0 = {0,10,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,11,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT};
int[] a1 = {10,0,18,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,16,graph.MAX_WEIGHT,12};
int[] a2 = {graph.MAX_WEIGHT,graph.MAX_WEIGHT,0,22,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,8};
int[] a3 = {graph.MAX_WEIGHT,graph.MAX_WEIGHT,22,0,20,graph.MAX_WEIGHT,graph.MAX_WEIGHT,16,21};
int[] a4 = {graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,20,0,26,graph.MAX_WEIGHT,7,graph.MAX_WEIGHT};
int[] a5 = {11,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,26,0,17,graph.MAX_WEIGHT,graph.MAX_WEIGHT};
int[] a6 = {graph.MAX_WEIGHT,16,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,17,0,19,graph.MAX_WEIGHT};
int[] a7 = {graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,16,7,graph.MAX_WEIGHT,19,0,graph.MAX_WEIGHT};
int[] a8 = {graph.MAX_WEIGHT,12,8,21,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,graph.MAX_WEIGHT,0};
graph.matrix[0] = a0;
graph.matrix[1] = a1;
graph.matrix[2] = a2;
graph.matrix[3] = a3;
graph.matrix[4] = a4;
graph.matrix[5] = a5;
graph.matrix[6] = a6;
graph.matrix[7] = a7;
graph.matrix[8] = a8;
System.out.println("深度优先遍历");
graph.depthFirstSearch();
System.out.println("广度优先遍历");
graph.broadFirstSearch();
/* int degree = graph.getOutDegree(2);
System.out.println("出度:"+degree);
int weigth = graph.getWeigth(0,4);
System.out.println("权值:"+weigth);
*/
graph.prim();
}
}