大家知道,图这种数据结构在java中有邻接表与邻接矩阵这两种存储方式,前者编程相对复杂但是效率较高,后者编程相对简单但是效率较低,我们利用java可以很容易的实现这两种数据结构。代码如下
邻接矩阵的存储方式:
public class MGraph {
private int[][] edges;//邻接矩阵
private int numOfEdges;//边的数目
private int numOfVetex;//顶点的数目
//初始化一个邻接矩阵
public MGraph(int n) {
edges = new int[n][n];
numOfEdges = 0;
numOfVetex = n;
}
//初始化一个邻接矩阵并且以一个n*n的矩阵为其赋值
public MGraph(int[][] edges,int n){
numOfVetex=n;
numOfEdges=0;
this.edges = new int[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
this.edges[i][j]=edges[i][j];
if((edges[i][j]!=-1)&&(edges[i][j]!=0)){
numOfEdges++;
}
}
}
}
//从某一个顶点开始对该图进行深度优先搜索
public void DFS(int v) {
int[] visited = new int[numOfVetex];
for (int i = 0; i < numOfVetex; i++) {
visited[i] = 0;
}
DFSREC(v, visited);
System.out.println();
int flag=1;
for(int i=0;i<visited.length;i++){
if(visited[i]==0)
{
flag=0;
break;
}
}
if(flag==1)
System.out.println("已遍历完全图");
else
System.out.println("从该点出发无法遍历全图");
}
//深度优先搜索辅助函数
private void DFSREC(int v, int visited[]) {
visited[v] = 1;
System.out.print(v + "-->");
for (int i = 0; i < numOfVetex; i++) {
if (edges[v][i] != -1 && edges[v][i] != 0 && visited[i] != 1) {
DFSREC(i, visited);
}
}
}
//广度优先搜索
public void BFS(int v) {
int[] qu=new int[numOfVetex];
int[] visited=new int[numOfVetex];
int head=0;
int tail=0;
qu[tail++]=v;
visited[v]=1;
while(head!=tail){
int t=qu[head++];
System.out.print(t+"-->");
for(int i=0;i<numOfVetex;i++){
if(edges[t][i]!=-1&&edges[t][i]!=0&&visited[i]==0)
{
qu[tail++]=i;
visited[i]=1;
}
}
}
}
//测试该图是否为连通图
public boolean isConnect(){
int[] visited = new int[numOfVetex];
for (int i = 0; i < numOfVetex; i++) {
visited[i] = 0;
}
DFSREC(0, visited);
for(int i=0;i<visited.length;i++){
if(visited[i]==0)
return false;
}
return true;
}
//输出从顶点u至顶点v的所有长度为l的路径
//path数组用来记录当前已经走过的路径
//d用来代表当前走过的长度
private void pathAllREC(int u,int v,int l,int d,int[] visited,int[] path){
visited[u]=1;
d++;
path[d]=u;
if(u==v&&d==l){
for(int i=0;i<=d;i++)
if(i==d){
System.out.print(path[i]);
}
else{
System.out.print(path[i]+"-->");
}
}
else{
for(int t=0;t<numOfVetex;t++){
if(visited[t]!=1&&edges[u][t]!=0&&edges[u][t]!=-1){
pathAllREC(t, v, l, d, visited, path);
}
}
visited[u]=0;
}
}
//输出从顶点u至顶点v的所有长度为l的路径
//path数组用来记录当前已经走过的路径
//d用来代表当前走过的长度
public void pathAll(int u,int v,int l){
int d=-1;
int[] visited=new int[numOfVetex];
int[] path=new int[numOfVetex];
pathAllREC(u,v,l,d,visited,path);
}
public static void main(String args[]){
int[][] edges={{0,2,-1,-1},{-1,0,3,1},{-1,-1,0,4},{5,-1,-1,0}};
MGraph m=new MGraph(edges,4);
m.pathAll(0, 3, 3);
// if(m.isConnect()==true)
// System.out.println("YES");
}
}
邻接表的存储方式:
package Graph;
import java.util.ArrayList;
public class LGraph {
//顶点表节点
private class VNode{
int data; //起点的序号
ArcNode firstArc; //指向第一条边
public VNode(int data, ArcNode firstArc) {
this.data = data;
this.firstArc = firstArc;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public ArcNode getFirstArc() {
return firstArc;
}
public void setFirstArc(ArcNode firstArc) {
this.firstArc = firstArc;
}
}
//边表结点
private class ArcNode{
int adjvex; //该边指向终点的序号
ArcNode nextarc; //下一条边的指针
int len; //该边的长度
public ArcNode(int adjvex, ArcNode nextarc, int len) {
super();
this.adjvex = adjvex;
this.nextarc = nextarc;
this.len = len;
}
public int getAdjvex() {
return adjvex;
}
public void setAdjvex(int adjvex) {
this.adjvex = adjvex;
}
public ArcNode getNextarc() {
return nextarc;
}
public void setNextarc(ArcNode nextarc) {
this.nextarc = nextarc;
}
public int getLen() {
return len;
}
public void setLen(int len) {
this.len = len;
}
}
ArrayList<VNode> vNodes;
int numOfVetex;
int numOfEdges;
public LGraph() {
vNodes=new ArrayList<VNode>();
numOfVetex=0;
numOfEdges=0;
}
public LGraph(int[][] edges,int n){
numOfVetex=n;
numOfEdges=0;
vNodes=new ArrayList<VNode>();
for(int i=0;i<n;i++){
VNode v=new VNode(i,null);
vNodes.add(v);
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(edges[i][j]!=0&&edges[i][j]!=-1){
ArcNode arc=new ArcNode(j,null,edges[i][j]);
VNode v=vNodes.get(i);
arc.setNextarc(v.getFirstArc());
v.setFirstArc(arc);
numOfEdges++;
}
}
}
public void disp(){
for(int i=0;i<vNodes.size();i++){
System.out.print("Node:"+vNodes.get(i).getData());
ArcNode arc=vNodes.get(i).getFirstArc();
while(arc!=null){
System.out.print("-->"+arc.getAdjvex());
arc=arc.getNextarc();
}
System.out.println();
}
}
//深度优先搜索的辅助函数
private void DFSREC(int v,int visited[]){
System.out.print(v+"-->");
visited[v]=1;
ArcNode arc=vNodes.get(v).getFirstArc();
while(arc!=null){
if(visited[arc.getAdjvex()]==0)
DFSREC(arc.getAdjvex(),visited);
arc=arc.getNextarc();
}
}
//深度优先搜索
public void DFS(int v){
int[] visited=new int[numOfVetex];
DFSREC(v,visited);
}
//广度优先搜索
public void BFS(int v){
int[] qu=new int[numOfVetex];
int tail=0;
int head=0;
int[] visited=new int[numOfVetex];
qu[tail++]=v;
while(head!=tail){
int t=qu[head++];
visited[t]=1;
System.out.print(t+"-->");
ArcNode arc=vNodes.get(t).getFirstArc();
while(arc!=null){
if(visited[arc.getAdjvex()]!=1){
qu[tail++]=arc.getAdjvex();
}
arc=arc.getNextarc();
}
}
}
//将邻接表存储的图转化为矩阵存储的图
public MGraph toMGraph(){
int[][] edges=new int[numOfVetex][numOfVetex];
for(int i=0;i<vNodes.size();i++){
edges[i][i]=0;
ArcNode arc=vNodes.get(i).getFirstArc();
while(arc!=null){
edges[i][arc.getAdjvex()]=arc.getLen();
arc=arc.getNextarc();
}
}
MGraph m=new MGraph(edges,numOfVetex);
return m;
}
public static void main(String args[]){
int[][] edges={{0,2,-1,-1},{-1,0,3,1},{-1,-1,0,4},{5,-1,-1,0}};
LGraph l=new LGraph(edges,4);
MGraph m=l.toMGraph();
// m.DFS(0);
}
}