图的邻接表的实现

上篇文章介绍了图的邻接矩阵的实现,本文即介绍图的另一种实现方法-邻接表

邻接表的实现原理

使用邻接矩阵实现图,对于n个顶点的图,即使是有向图也需要O(n^2)。实际上,如此大的空间足以容纳所有潜在的弧。然而实际应用所处理的图,所含的
边通常远远少于O(n^2)。比如在平面图之类的稀疏图(sparse graph)中,边数渐进地不超过O(n),仅与顶点总数大致相当。
由此可见,邻接矩阵的空间效率之所以低,是因为其中大量单元所对应的弧,并未在图中出现。类似的问题也出现的树的顺序存储结构,对应的也可以通过链式存储的方法来改变。
按照这一思路,的确可以导出图结构的另一种表示与实现形式。

这里写图片描述

以图a所示的无向图为例,只需将如图b所示的邻接矩阵,逐行地转换为图c所示的一组列表,即可分别记录各顶点的关联边(或等价地,邻接顶点)。这些表便称之为邻接表(adjacency list)。

图到邻接表的转化过程

以上图为例,对于图a的四个顶点A,B,C,D四个顶点的属性上添加一个对于弧的指针,指向以该顶点为起点的一条弧(被称为该顶点为起点的所有弧的首弧)。而对于弧的属性也增加一个对顶点的指针和对弧的指针,其中对于顶点的指针指向该弧的终点(弧头),而对弧的指针指向已该弧的起点(弧尾)的另一条弧。
这样,根据一个顶点的弧的指针,通过这个弧对于其他的弧的指针即可定义出该顶点作为起点(弧尾)的所有弧。也可以根据一个顶点的弧的指针,通过这个弧对于弧的终点的指针(弧头)便可定义出由该顶点起的一条路。

节点的实现
public class Node<T> {

    private T data; // 存储的数据
    private Edge head; // 该节点作为弧的起点(弧尾)的首弧
    private int outDegree; // 出度
    private int inDegree; // 入度
    //以下属性在遍历中使用
    private int status = 0;  
    //状态 0 undiscovered  1 discovered   2 visited
    //此处应该使用枚举,笔者偷懒了
    private int parent = -1;
    private int dTime = -1; //开始遍历的时间
    private int fTime = -1; //结束遍历的时间

    //省掉getter和setter...
    public void addInDegree() {
        this.inDegree++;
    }

    protected void addOutDegree() {
        this.outDegree++;
    }

    protected void delInDegree() {
        this.inDegree--;
    }

    protected void delOutDegree() {
        this.outDegree--;
    }

    //设置一条也该节点为起点的弧
    protected void setEdge(Edge edge) {
        // 从该节点的弧链接头指针出发
        Edge nextNull = ge
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值