数据结构学习之图——图的存储结构

图的存储结构主要分为两种:邻接矩阵和邻接表

1.图的邻接矩阵

邻接矩阵是表示顶点之间邻接关系的矩阵。设G=(V,E)是含有n(设n>0)个顶点的图,各顶点的编号为0~n-1,则G的邻接矩阵数组A是n阶方阵。

 

代码如下:

/**
 * 
 */
package class8;


import java.lang.*;
import java.util.*;
public class MatGraphClass				//图邻接矩阵类
{	final int MAXV=100;					//表示最多顶点个数
	final int INF=0x3f3f3f3f;			//表示∞,整数的两倍不超过 0x7f7f7f7f,即int能表示的 
                                        //最大正整数。
	int[][] edges;						//邻接矩阵的边数组,假设元素为int类型
	int n,e;							//顶点数,边数
	String[] vexs;						//存放顶点信息
	public MatGraphClass()				//构造方法
	{
		edges=new int[MAXV][MAXV];
		vexs=new String[MAXV];
	}
	public void CreateMatGraph(int[][] a,int n,int e)	//通过边数组a、顶点数n和边数e来建立图的邻接矩阵
	{
		this.n=n; this.e=e;					//置顶点数和边数
		for (int i=0;i<n;i++)
		{
			edges[i]=new int[n];
			for (int j=0;j<n;j++)
				edges[i][j]=a[i][j];
		}
	}
	public void DispMatGraph()				//格式化输出图的邻接矩阵
	{
		for (int i=0;i<n;i++)
		{	for (int j=0;j<n;j++)
				if (edges[i][j]==INF)
					System.out.printf("%4s","∞");
				else
					System.out.printf("%5d",edges[i][j]);
			System.out.println();
		}
	}
	public static void main(String[] args) {
			MatGraphClass g=new MatGraphClass();
			int n=5,e=5;
			int[][] a={{0,8,g.INF,5,g.INF},{g.INF,0,3,g.INF,g.INF},
				{g.INF,g.INF,0,g.INF,16},{g.INF,9,g.INF,0,g.INF},{g.INF,g.INF,g.INF,g.INF,0}};
			g.CreateMatGraph(a,n,e);
			g.DispMatGraph();
	}
}

 

2.邻接表

邻接表分成两部分,左侧为一个顶点数组,右侧为表节点,核心思想为找邻居。

假设从0号顶点开始(可以从任意顶点开始,顺序不影响结果),则将0号顶点放在数组的0号位置,与0号顶点直连的有1号、3号、4号三个顶点,将之依次插入到0号右侧(1,2,3号位置可以随机插入,对结果无影响)。注意为了方便在后续算法中(如深度优先遍历,广度优先遍历)使用该存储结构,这里在链节点中存入的值是节点编号。

 

代码如下:

/**
 * 
 */
package class8;

import java.lang.*;
import java.util.*;
@SuppressWarnings("unchecked")
class ArcNode							//边结点类
{	int adjvex;							//该边的终点编号
	ArcNode nextarc;					//指向下一条边的指针
	int weight;							//该边的相关信息,如边的权值
}

class VNode								//表头结点类型
{	String[] data;						//顶点信息
	ArcNode firstarc;					//指向第一条边的相邻顶点
}

public class AdjGraphClass				//图邻接表类
{	final int MAXV=100;					//表示最多顶点个数
	final int INF=0x3f3f3f3f;			//表示∞	
	VNode[] adjlist;					//邻接表头数组
	int n,e;							//图中顶点数n和边数e
	public AdjGraphClass()				//构造方法
	{
		adjlist=new VNode[MAXV];
		for (int i=0;i<MAXV;i++)
		{
			adjlist[i]=new VNode();
		}
	}
	public void CreateAdjGraph(int[][] a,int n,int e)	//通过边数组a、顶点数n和边数e来建立图的邻接表
	{
		this.n=n; this.e=e;								//置顶点数和边数
		ArcNode p;			
		for (int i=0;i<n;i++)							//检查边数组a中每个元素
		{
			adjlist[i].firstarc=null;                   //给邻接表中所有头结点的指针置初值
			for (int j=n-1;j>=0;j--)
				if (a[i][j]!=0 && a[i][j]!=INF)			//存在一条边
				{	p=new ArcNode();					//创建一个边结点p
					p.adjvex=j;                         //存入节点编号
					p.weight=a[i][j];                   //存入节点权值
					p.nextarc=adjlist[i].firstarc;		//采用头插法插入*p
					adjlist[i].firstarc=p;
				}
		}
		}
	public void DispAdjGraph()				//输出图的邻接表
	{
		ArcNode p;
		for (int i=0;i<n;i++)
		{
			System.out.printf("  [%d]",i);
			p=adjlist[i].firstarc;			//p指向第一个邻接点
			while (p!=null)
			{	
				System.out.printf("->(%d,%d)",p.adjvex,p.weight);
				p=p.nextarc;				//p移向下一个邻接点
			}
			System.out.println("->∧");
		}
	}
	public static void main(String[] args) {

		AdjGraphClass G=new AdjGraphClass();
		int n=5,e=5;
		int[][] a={{0,8,G.INF,5,G.INF},
		{G.INF,0,3,G.INF,G.INF},
			{G.INF,G.INF,0,G.INF,16},
			{G.INF,G.INF,9,0,G.INF},
			{G.INF,G.INF,G.INF,G.INF,0}};
		G.CreateAdjGraph(a,n,e);
		G.DispAdjGraph();
	}
}

 

参考书目:

  1. 李春葆、李筱驰,《数据结构教程—Java语言描述》,清华大学出版社 2020年9月版
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值