import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Scanner;
public class AdjList
{
private int V;//顶点
private int E;//边
private LinkedList<Integer> [] adj;//邻接表
public AdjList(String filename)
{//从文件中读取图的信息,并构建一个无向图
File file=new File(filename);
try(Scanner scanner=new Scanner(file))
{//这样写不用考虑回收资源
V=scanner.nextInt();//读取图的顶点数
if(V<0)
{//由于一个图最少有一个顶点,于是要考虑到方方面面的情况
throw new IllegalArgumentException("V must be non-negative");
}
adj=new LinkedList[V];//使用读取进来的第一行的数字创建一个邻接表
//由于java语法的特点邻接表的创建只能使用这种形式
//先进行链表的创建,在进行对链表中每一个节点进行空间申请的操作
for(int i=0;i<V;i++)
{//对链表中的每一个节点进行申请空间
//adj[i]指的是与第i个顶点直接相连的顶点所构成的节点链表
adj[i]=new LinkedList<Integer>();//这里可以使用类型推断,在这里略去
}
E=scanner.nextInt();//再度入图的边数
if(E<0)
{//由于一个图最少有一个顶点,于是要考虑到方方面面的情况
throw new IllegalArgumentException("E must be non-negative");
}
for(int i=0;i<E;i++)
{
//读入各个顶点的信息,顺带判断合法性
int a=scanner.nextInt();
validateVertex(a);
int b=scanner.nextInt();
validateVertex(b);
//判断是否为自环边
if(a==b)//如果某一条边的头尾节点都指向了同一个顶点,那么久认为这是一条自环边
{
throw new IllegalArgumentException("Self Loop is Detected!");
}
if(adj[a].contains(b))//如果已经有了这样的一条边,就认为他是一条平行边
{
throw new IllegalArgumentException("Parallel edges are detected!");
}
//根据各个顶点的信息,对邻接表进行追加元素操作
adj[a].add(b);//基于无向图考虑
adj[b].add(a);
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
private void validateVertex(int v)
{//判断边的信息是否正确,比如:有没有某一个边的序号小于0,或者大于V
if(v<0||v>V)
{
throw new IllegalArgumentException("Vertex "+v+" is invalid");
}
}
public int V()//为用户提供接口来访问节点数以及边数
{
return V;
}
public int E()
{
return E;
}
public boolean hasEdge(int v,int w)//判断两个顶点之间是否存在一条边
{
validateVertex(v);
validateVertex(w);
return adj[v].contains(w);
}
public LinkedList<Integer> adj(int v)//返回与顶点v相邻的边
{
validateVertex(v);
return adj[v];
}
public int degree(int v)//返回某一节点的度
{
return adj(v).size();
}
@Override
public String toString()//重写toString()方法来打印图
{
StringBuilder sb=new StringBuilder();//创建StringBuilder的对象用来操作字符串
sb.append(String.format("V = %d,E = %d\n", V,E));//首先输出有关图的信息
for(int v=0;v<V;v++)//v表示各个顶点的下标
{
sb.append(String.format("%d :", v));//控制输出的每一行的最左侧格式
for(int w:adj[v])
{
sb.append(String.format("%d ", w));//使用增强for循环来对邻接表中的每一链表中的元素进行遍历
}
sb.append("\n");
}
return sb.toString();
}
public static void main(String []args)
{
AdjList adjList=new AdjList("g.txt");//传入图文件,并创建一个图
System.out.println(adjList);
}
}
使用邻接表表示图(无向无权图)
猜你喜欢
转载自blog.csdn.net/dosdiosas_/article/details/105693516
今日推荐
周排行