图的邻接表实现(Java)

图的邻接表实现(Java)

当图的结点多边少(又称为稀疏图)的时候,相比使用邻接矩阵存储,使用邻接表存储图的空间效率更高。
使用邻接表存储图的时候,图的每个结点对应一个边链表,也就是说,每个结点所包含的边构成一个链表。例如结点A和B相连,A也和C相连,若边e1表示A和B之间的边,e2表示A和C之间的边,那么结点A包含的边链表就是e1->e2,其中e1保存着A的临接点B,e2保存着A的临接点C。


Graph.java

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

//实现图的邻接表结构
class Edge {//边:作为邻接表中每个结点的边链表的元素,例如结点A和B构成边e1,那么A拥有e1,在A的边链表中,e1的verAdj = B
    int verAdj;
    int weight;
    Edge nextEdge;//如果结点A拥有多条边,边构成链表,例如e1->e2->...->en
}
class Vertex{
    int verName;
    Edge edgeHead;//边链表的头指针
}
public class Graph {
    private Vertex[] vertexs;
    private boolean isDirected;//若为有向图,则isDirected为true

    Graph(int[] vexs,int[][] edges,boolean isDirected){//图的初始化
        //vexs包含各顶点的编号,若有n个顶点,顶点的编号范围是0~n-1
        //edges是一个n×3的数组,,边的权值等于edges[i][2],若为有向图,那么edges[i][0]指向edges[i][1]
        vertexs = new Vertex[vexs.length];
        this.isDirected = isDirected;
        if(isDirected == false){//无向图的初始化
            for (int j = 0; j < vexs.length; j++) {
                vertexs[j] = new Vertex();
                vertexs[j].verName = vexs[j];
                Edge cur = null;
                for (int i = 0; i < edges.length; i++) {
                    if(edges[i][0] == vexs[j]){
                        if(vertexs[j].edgeHead == null){
                            vertexs[j].edgeHead = new Edge();
                            vertexs[j].edgeHead.verAdj = edges[i][1];
                            vertexs[j].edgeHead.weight = edges[i][2];
                            cur = vertexs[j].edgeHead;
                        }else{
                            while(cur.nextEdge != null) cur = cur.nextEdge;
                            cur.nextEdge = new Edge();
                            cur = cur.nextEdge;
                            cur.verAdj = edges[i][1];
                            cur.weight = edges[i][2];
                        }   
                    }else if(edges[i][1] == vexs[j]){
                        if(vertexs[j].edgeHead == null){
                            vertexs[j].edgeHead = new Edge();
                            vertexs[j].edgeHead.verAdj = edges[i][0];
                            vertexs[j].edgeHead.weight = edges[i][2];
                            cur = vertexs[j].edgeHead;
                        }else{
                            while(cur.nextEdge != null) cur = cur.nextEdge;
                            cur.nextEdge = new Edge();
                            cur = cur.nextEdge;
                            cur.verAdj = edges[i][0];
                            cur.weight = edges[i][2];
                        }   
                    }
                }
            }
        }else{//有向图的初始化
            for (int j = 0; j < vexs.length; j++) {
                vertexs[j] = new Vertex();
                vertexs[j].verName = vexs[j];
                Edge cur = null;
                for (int i = 0; i < edges.length; i++) {
                    if(edges[i][0] == vexs[j]){
                        if(vertexs[j].edgeHead == null){
                            vertexs[j].edgeHead = new Edge();
                            vertexs[j].edgeHead.verAdj = edges[i][1];
                            vertexs[j].edgeHead.weight = edges[i][2];
                            cur = vertexs[j].edgeHead;
                        }else{
                            while(cur.nextEdge != null) cur = cur.nextEdge;
                            cur.nextEdge = new Edge();
                            cur = cur.nextEdge;
                            cur.verAdj = edges[i][1];
                            cur.weight = edges[i][2];
                        }   
                    }
                }
            }
        }
    }
    void bfs(){//广度优先遍历
        if(vertexs == null || vertexs.length == 0) return;
        Queue<Vertex> queue = new LinkedList<Vertex>();
        boolean[] visited = new boolean[vertexs.length];
        for (int i = 0; i < visited.length; i++) {
            visited[i] = false;
        }
        queue.offer(vertexs[0]);
        visited[0] = true;
        System.out.print(vertexs[0].verName);
        while(!queue.isEmpty()){
            Vertex v = queue.remove();
            Edge e = v.edgeHead;
            while(e != null && visited[e.verAdj] == false){
                queue.offer(vertexs[e.verAdj]);
                visited[e.verAdj] = true;
                System.out.print(e.verAdj + " ");
                e = e.nextEdge;
            }
        }
    }
    void dfsNonRec(){//邻接表非递归深度优先遍历
        if(vertexs == null || vertexs.length == 0) return;
        boolean[] visited = new boolean[vertexs.length];
        for (int i = 0; i < visited.length; i++) {
            visited[i] = false;
        }
        Stack<Vertex> stack = new Stack<Vertex>();
        stack.push(vertexs[0]);
        visited[0] = true;
        while(!stack.isEmpty()){
            Vertex v = stack.pop();
            visited[v.verName] = true;
            System.out.print(v.verName + " ");
            Edge e = v.edgeHead;
            while(e != null && visited[e.verAdj] != true){
                stack.push(vertexs[e.verAdj]);
                e = e.nextEdge;
            }
        }
    }
    void dfs(){//dfs和dfsRec共同实现邻接表存储的图的递归深度优先遍历
        if(vertexs == null || vertexs.length == 0) return;
        boolean[] visited = new boolean[vertexs.length];
        dfsRec(visited, vertexs[0]);
    }
    void dfsRec(boolean[] visited,Vertex vertex){
        if(vertex == null) return;
        visited[vertex.verName] = true;
        System.out.print(vertex.verName + " ");
        Edge e = vertex.edgeHead;
        while(e != null){
            if(visited[e.verAdj] != true){
                dfsRec(visited, vertexs[e.verAdj]);
            }
            e = e.nextEdge;
        }
    }
    void printGraph(){
        if(isDirected == false){
            for (Vertex vertex : vertexs) {
                Edge e = vertex.edgeHead;
                while(e != null){
                    System.out.println(vertex.verName + "--" + e.verAdj + "  weight = " + e.weight);
                    e = e.nextEdge;
                }
            }
        }else{
            for (Vertex vertex : vertexs) {
                Edge e = vertex.edgeHead;
                while(e != null){
                    System.out.println(vertex.verName + "->" + e.verAdj + "  weight = " + e.weight);
                    e = e.nextEdge;
                }
            }
        }       
    }
}

Main.java

public class Main{
     public static void main(String[] args){
         int[] vexs = {0,1,2,3,4,5};
         int[][] edges = {{0,1,100},{0,2,100},{0,3,100},{1,4,100},{2,5,100},{4,5,100},{5,3,100}};
         Graph g = new Graph(vexs, edges,true);
         g.bfs();
         //g.dfs();
         //g.dfsNonRec();
     }
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值