import java.util.Scanner;
/**
* 邻接矩阵存储的图
* @author liangxiamoyi
*
*/
public class Graph_Matrix {
/**
* 图中最大顶点个数
*/
public static int MAXGRAPHSIZE=256;
/**
* 图中最大权值
*/
public static int MAXWEIGHT=1000;
/**
* 邻接矩阵
*/
private int[][] edge;
/**
* 当前图中顶点个数
*/
private int graphSize;
/**
* 构造方法
*/
public Graph_Matrix(){
this.edge=new int[MAXGRAPHSIZE][MAXGRAPHSIZE];
System.out.println("请输入顶点个数:");
Scanner sc=new Scanner(System.in);
this.graphSize=sc.nextInt();
System.out.println("请依次输入每条边的权值:(无穷大为1000,无穷小为0)");
for(int i=0;i<this.graphSize;i++){
for(int j=0;j<this.graphSize;j++){
this.edge[i][j]=sc.nextInt();
}
}
}
/**
* 取得序号为v的顶点的第一个邻接顶点的序号
* @param v 序号v
* @return 第一个邻接顶点的序号
*/
public int getFirstNeighbor(int v){
if(v==-1)return -1;
for(int i=0;i<this.graphSize;i++){
if(this.edge[v][i]>0&&this.edge[v][i]<MAXWEIGHT){
return i;
}
}
return -1;
}
/**
* 取得v1顶点相对于v2顶点的下一个邻接顶点
* @param v1 顶点v1
* @param v2 顶点v2
* @return 下一个邻接顶点的序号
*/
public int getNextNeighbor(int v1,int v2){
if(v1==-1||v2==-1){
return -1;
}
for(int i=v2+1;i<this.graphSize;i++){
if(this.edge[v1][i]>0&&this.edge[v1][i]<MAXWEIGHT){
return i;
}
}
return -1;
}
/**
* 插入一个顶点
*/
public void insertVertex(){
for(int i=0;i<this.graphSize;i++){
this.edge[i][graphSize]=MAXWEIGHT;
}
for(int i=0;i<this.graphSize;i++){
this.edge[graphSize][i]=MAXWEIGHT;
}
this.edge[graphSize][graphSize]=0;
this.graphSize++;
System.out.println("插入成功!");
return ;
}
/**
* 删除 一个顶点
* @param v 删除的顶点
*/
public void deleteVertex(int v){
if(v>=this.graphSize){
System.out.println("无此顶点");
return;
}
for(int i=0;i<this.graphSize;i++){
this.edge[v][i]=0;
this.edge[i][v]=0;
}
if(v==this.graphSize-1){
this.graphSize--;
return;
}
for(int i=v+1;i<this.graphSize;i++){
for(int j=0;j<this.graphSize;j++){
this.edge[i-1][j]=this.edge[i][j];
}
}
this.graphSize--;
}
/**
* 插入一条边
* @param v1 起点
* @param v2 终点
* @param weight 权值
*/
public void insertEdge(int v1,int v2,int weight){
if(v1==v2||v1>this.graphSize||v2>this.graphSize||this.edge[v1][v2]!=MAXWEIGHT){
System.out.println("插入失败!");
return;
}
this.edge[v1][v2]=weight;
System.out.println("插入成功!");
return;
}
/**
* 删除一条边
* @param v1 起点
* @param v2 终点
*/
public void deleteEdge(int v1,int v2){
if(v1==v2||v1>this.graphSize||v2>this.graphSize||this.edge[v1][v2]==MAXWEIGHT){
System.out.println("删除失败!");
return;
}
this.edge[v1][v2]=MAXWEIGHT;
System.out.println("删除成功");
return;
}
/**
* 求图中任意两点的最短路径
*/
public void allLengths(){
int n=this.graphSize;
int[][] path=new int[n][n];//相应路径上顶点j的前一个顶点
int[][] a=new int[n][n];//两点最短路径长度
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
a[i][j]=edge[i][j];
if(i!=j&&a[i][j]<MAXGRAPHSIZE)path[i][j]=i;
else path[i][j]=-1;
}
}
for(int k=0;k<n;k++){
for(int i=0;i<n;i++){
if(i!=k){
for(int j=0;j<n;j++){
if(j!=k&&j!=i&&a[i][k]<MAXGRAPHSIZE&&a[k][j]<MAXGRAPHSIZE&&a[i][k]+a[k][j]<a[i][j]){
a[i][j]=a[i][k]+a[k][j];
path[i][j]=path[k][j];
}
}
}
}
}
//输出
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i!=j&&a[j][i]<MAXGRAPHSIZE){
System.out.println("顶点"+j+"到"+"顶点"+i+"的最短路径长度:"+a[j][i]);
System.out.print("最短路径为:"+j);
int k=j;
while(path[i][k]!=i){
System.out.print(" "+path[i][k]);
k=path[i][k];
}
System.out.print(" "+i);
}
}
}
}
/**
* 对无向加权连通图,求最小支撑树的prim算法
*/
public void prim(){
int n=this.graphSize;
//权值最小的边类
class LV{
int lowCost;//权值
int vex;//边的终点
}
LV[] closeEdge=new LV[n];
//支撑树的边类
class Edge{
int head;//头
int tail;//尾
int cost;//权值
}
Edge[] te=new Edge[n-1];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(edge[i][j]==0)edge[i][j]=MAXWEIGHT;
}
}
//以顶点0为初始顶点,初始化数组closeEdge
for(int i=0;i<n;i++){
closeEdge[i]=new LV();
closeEdge[i].lowCost=edge[0][i];
closeEdge[i].vex=0;
}
closeEdge[0].vex=-1;//顶点0进入集合
int count=0;//支撑树的边数
for(int i=0;i<n;i++){
int min=MAXWEIGHT+1;
int v=0;
for(int j=0;j<n;j++){//求当前权值最小的边和该边的终点v
if(closeEdge[j].vex!=-1&&closeEdge[j].lowCost<min){
v=j;
min=closeEdge[j].lowCost;
}
}
//向支撑树的边集合中添加一条边
if(v!=0){
te[count]=new Edge();
te[count].head=closeEdge[v].vex;
te[count].tail=v;
te[count].cost=closeEdge[v].lowCost;
count++;
//顶点v进入集合U
closeEdge[v].lowCost=0;//修改域值
closeEdge[v].vex=-1;
for(int j=0;j<n;j++){
if(closeEdge[j].vex!=-1&&edge[v][j]<closeEdge[j].lowCost){
closeEdge[j].lowCost=edge[v][j];
closeEdge[j].vex=v;
}
}
}
}
for(int i=0;i<n-1;i++){
System.out.println("("+te[i].head+","+te[i].tail+","+te[i].cost+")");
}
}
//测试
public static void main(String[] args){
// 测试数据
// 0
// 2
// 7
// 1000
// 1
// 1000
// 0
// 1000
// 1000
// 1000
// 1000
// 1000
// 0
// 5
// 1000
// 1000
// 1000
// 1000
// 0
// 1000
// 3
// 1000
// 1000
// 4
// 0
Graph_Matrix gm=new Graph_Matrix();
System.out.println(gm.getFirstNeighbor(0));
System.out.println(gm.getNextNeighbor(0, 1));
gm.insertVertex();
gm.insertEdge(5, 0, 2);
gm.insertEdge(5, 1, 2);
gm.insertEdge(5, 4, 2);
System.out.println(gm.getFirstNeighbor(5));
System.out.println(gm.getNextNeighbor(5, 0));
gm.deleteEdge(5, 1);
System.out.println(gm.getFirstNeighbor(5));
System.out.println(gm.getNextNeighbor(5, 0));
gm.deleteVertex(5);
System.out.println(gm.getFirstNeighbor(5));
// 测试数据
// 0
// 1
// 4
// 3
// 1
// 0
// 1000
// 2
// 4
// 1000
// 0
// 5
// 3
// 2
// 5
// 0
Graph_Matrix g=new Graph_Matrix();
System.out.println("最小支撑树为:");
g.prim();
}
}
测试结果: