package graph;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/**
* @author 作者 E-mail:923861438@qq.com
* @date 创建时间:2016年10月6日 下午4:35:39
* @version 1.0
* @parameter
* @since
* @return
*/
public class Graph {
final int MIN=-256;
final int MAX=256;
int numVertexes;
int numEdges;
String []vex;
int acr[][];
public Graph()
{
vex=new String[MAX];
acr=new int[MAX][MAX];
}
// 建立无向网图, 给图中的 顶点内容 和 边权重 赋值
public void buildGraph(Graph g)
{
//读入顶点数和边数
System.out.println("请输入顶点数:\n");
Scanner sc=new Scanner(System.in);
numVertexes=sc.nextInt();
System.out.println("请输入边数:\n");
numEdges=sc.nextInt();
//读入顶点信息,建立顶点表
for(int i=0;i<g.numVertexes;i++)
{
System.out.print("第"+i+"个顶点信息为:");
vex[i]=sc.next();
}
//邻接矩阵初始化
for(int i=0;i<g.numVertexes;i++)
for(int j=0;j<g.numVertexes;j++)
{
g.acr[i][j]=MIN;
}
//读入边信息,建立邻接矩阵
for(int k=0;k<g.numEdges;k++)
{
System.out.println("请输入边(i,j)的下标i:\n");
int i=sc.nextInt();
System.out.println("请输入边(i,j)的下标j:\n");
int j=sc.nextInt();
System.out.println("请输入边(i,j)的权重w:\n");
int w=sc.nextInt();
g.acr[i][j]=w;
g.acr[j][i]=g.acr[i][j];
}
sc.close();
}
public void printGraph(Graph g)
{
System.out.print(" ");
for(int i=0;i<g.numVertexes;i++)
{
System.out.print(g.vex[i]+" ");
}
for(int i=0;i<g.numVertexes;i++)
{
System.out.println();
System.out.print(g.vex[i]+" ");
for(int j=0;j<g.numVertexes;j++)
{
System.out.print(g.acr[i][j]+" ");
}
}
}
//深度优先遍历
public void DFSTraverse(Graph g)
{
//建立访问数组
boolean []visited=new boolean [g.numVertexes];
//初始化 访问顶点
for(int i=0;i<visited.length;i++)
visited[i]=false;
//对未访问顶点调用DFS
for(int i=0;i<visited.length;i++)
if(!visited[i])
DFS(g,i,visited);
}
//从顶点i开始进行的深度优先搜索DFS
public void DFS(Graph g, int i, boolean[] visited) {
visited[i]=true;
System.out.print("已访问"+g.vex[i]+" ");
for(int j=0;j<g.numVertexes;j++)
{
if(g.acr[i][j]>0 && !visited[j])
DFS(g,j,visited);
}
}
//广度优先搜索
public void BFS(Graph g)
{
int i=0;
Queue<Integer> q=new LinkedList<Integer>();
//建立访问数组
boolean visited[]=new boolean [MAX];
//初始化 访问顶点
for(i=0;i<g.numVertexes;i++)
visited[i]=false;
//对每个顶点做循环
for( i=0;i<g.numVertexes;i++)
{
if(!visited[i])
{
visited[i]=true;
System.out.print("已访问"+g.vex[i]+" ");
q.offer(i);
while(!q.isEmpty())
{
i=q.poll();
for(int j=0;j<g.numVertexes;j++)
{
if(g.acr[i][j]>0 && !visited[j])
{
visited[j]=true;
System.out.print("已访问"+g.vex[j]+" ");
q.offer(j);
}
}
}
}
}
}
/* 最小生成树之普利姆(Prim)算法
* 1.定义和初始化lowcost和adjvex数组
* 2.大循环里面构造最小生成树
* (1)从剩下顶点中寻找lowcost最小值及其下标k
* (2) 输出并将顶点k加入生成树
* (3)用k周边的较小权重去更新lowcost数组,用k更新adjvex数组
*
*
*/
public void MiniSpanTree_Prim(Graph G)
{
int min, i, j, k;
//定义lowcost和adjvex数组
int [] adjvex = new int[G.numVertexes]; //保存 已 加入生成树的顶点下标
int [] lowcost = new int[G.numVertexes]; //保存 已加入生成树的各顶点上最小权值的边权重
//初始化lowcost和adjvex数组
lowcost[0] = 0; //保存相关顶点间边的权值,并判断顶点是否已加入生成树。lowcost[k]=0,表示顶点k已加入生成树
adjvex[0] = 0; //初始化第一个顶点下标为0,从v0开始
for(i = 1;i < G.numVertexes;i++)
{
lowcost[i] = G.acr[0][i]; //将v0顶点与其他顶点间边的权值存入数组
adjvex[i] = 0; //初始化都为v0的下标0
}
//整个循环过程,就是构造最小生成树的过程
for(i = 1;i < G.numVertexes;i++)
{
min = MAX; //初始化最小权值为MAX
k = 0;
//从剩下顶点中寻找lowcost最小值及其下标k
for(j=1;j<G.numVertexes;j++)
{
if(lowcost[j] != 0 && lowcost[j] < min)
{
min = lowcost[j];
k = j;
}
}
//输出并将顶点k加入生成树
System.out.println("("+adjvex[k]+", "+k+")"+" 权长:"+G.acr[adjvex[k]][k]); //打印当前顶点边中权值最小的边
lowcost[k] = 0; //将当前顶点的权值设为0,表示此顶点已加入生成树
//已加入k顶点,用k周边的较小权重去更新lowcost数组和adjvex数组
for(j = 1;j < G.numVertexes;j++)
{
if(lowcost[j] != 0 && G.acr[k][j] < lowcost[j])
{ //如果下标为k的顶点各边权值小于此前这些顶点未被加入生成权值
lowcost[j] = G.acr[k][j]; //将较小的权值存入lowcost
adjvex[j] = k; //将下标为k的顶点存入adjvex
}
}
}
}
public static void main(String []args)
{
Graph g=new Graph();
g.buildGraph(g);
g.printGraph(g);
System.out.println();
System.out.println("深度优先搜索结果:");
g.DFSTraverse(g);
System.out.println();
System.out.println("广度优先搜索结果:");
g.BFS(g);
}
}
数据结构之最小生成时Prim算法 java
最新推荐文章于 2022-04-02 10:42:37 发布