无向图

无向图

1、术语

图: 图是由一组顶点和一组能够将两个顶点相连的边组成

连通图: 从任意一个顶点都存在一条路径到达另一个任意顶点
非连通图无环图

子图:由一幅图的所有边的一个子集(以及它们所依附的所有顶点)组成的图

无环 连通
生成树:连通图的子图,他含有图中的所有顶点且是一棵


图的密度:已经连接的顶点对占所有可能被连接的顶点对的比例
稀疏图:被连接的顶点对很少
稠密图:只有少部分顶点对之间没有边连接


2、无向图的数据结构

图的基本操作API

第二个构造函数的输入由 2 E + 2 2E+2 2E+2 个整数组成:首先是 V V V(顶点数),然后是 E E E(边数),再然后是 E E E对由整数对构成的边。
这里写图片描述
在这里插入图片描述

图的表示方法

用哪种方式(数据结构)来表示图。
在这里插入图片描述


图的数据结构

非稠密图的标准表示为邻接表,它将每个顶点的所有相邻顶点都保存在该顶点对应的元素所指向的一张链表
注意,边的插入顺序决定了Graph的邻接表中顶点的出现顺序。输入的第一个相邻顶点在链表中排在最后。

这里使用Bag抽象数据类型来实现这个链表。如果需要扩展功能(如:添加删除顶点或边、检验一条边是否存在),则 可以用 符号表(ST) 或 SET 代替 Bag。
这里写图片描述 在这里插入图片描述

/*Graph数据类型*/
public class Graph{
    private final int V;    //顶点数目
    private int E;          //边的数目
    private Bag<Integer>[] adj; //邻接表

    public Graph(int V){
        this.V = V; this.E = 0;
        adj = (Bag<Integer>[]) new Bag[V];    //创建邻接表
        for(int v = 0; v < V; v++){           //将所有链表初始化为空
            adj[v] = new Bag<Integer>();
        }
    }

    public Graph(In in){
        this(in.readInt());      //读取V并将图初始化
        int E = in.readInt();    //读取E
        for(int i = 0;i < E; i++){
            int v = in.readInt();
            int w = in.readInt();
            addEdge(v, w);       //添加一条连接v、w的边   
        }
    }

    public int V(){ return V; }
    public int E(){ return E; }

    public void addEdge(int v, int w){
        adj[v].add(w);
        adj[w].add(v);
        E++;
    }
    public Iteralbe<Integer> adj(int v){
        return adj[v];
    }
    
    /*图的邻接表的字符串表示*/
	public String toString(){
	    String s = V + " vertices, " + E +" edges \n";
	    for (int v = 0; v < V; v++){
	        s += v + ": ";
	        for (int w : this.adj(v))
	            s += w + " ";
	        s += "\n";
	   } 
	    return s;
	}
}

最常用的图处理代码

/*计算v的度数*/
public static int degree(Graph G, int v){
    int degree = 0;
    for (int w : G.adj(v)) degree++;
    return degree;
}
/*计算所有顶点的最大度数*/
public static int maxDegree(Graph G){
    int max = 0;
    for (int v = 0; v < G.V(); v++){
        if (degree(G, v) > max)
            max = degree(G, v);
   }
}

/*计算所有顶点的平均度数*/
public static double avgDegree(Graph G){
   return 2.0*G.E()/G.V();
}
/*计算自环的个数*/
public static int numberOfSelfLoops(Graph G){
    int count = 0;
    for (int v = 0; v < G.V(); v++){
        for(int w : G.adj(v)){
            if (v == w)    count++;
       }
   }
    return count/2;   //每条边都被记过两次
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值