邻接矩阵存储图Java实现

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();
		
	}
}

测试结果:


  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值