图论—基本表示

图论 Graph Theory

图论涉及到的地方

交通运输、社交网络、互联网、工作安排、脑区活动、程序状态执行

比如交通运输

点代表着一个城市 而连接的线代表着另一个城市与这个城市的道路

社交网络这可以这样认为:点代表着人,连接代表着这个人是这个人的好友

 

图的分类

无向图 如人与人之间的认识(这个点连接过去,还要返回过去)

有向图 一个事件转移到另一个事件 有方向

 

 

权值

边的权重(或者称为权值、开销、长度等),也是一个非常核心的概念,即每条边都有与之对应的值。

比如交通运输,这个城市到另一个城市的边需要多少距离 这就是这个边的权值

 

有权图

无权图、边上没有值

有权上就有

 

自环边只有它自身的边

平行边:两个节点有多条连接的边 如城市交通 一个城市到另一个城市 有多条路一样的道理

稀疏图

 

稠密图
 

 

 

领接表适合表示稀疏图

领接矩阵符合表示稠密图

 

稀疏图 -邻接表从

这个是无向图。。

一个节点 一个节点的来

0只有与1有链接 就是 0 1

1有 0 1 3 2 最后就是 1 0 2 3

其他继续这样

 

这个是有向图

0只指向了1 结果 0 1

1指向了2   结果 1 2

 

代码

package com.binglian.Graph;

import java.awt.event.MouseWheelEvent;
import java.util.Vector;

//稀疏图 -邻接表
public class SparseGraph {

	
	private int n;//节点数
	private int m;//边数
	private boolean directed;	//是否为有向图
	private Vector<Integer>[] g;//图的具体数据
	
	public SparseGraph(int n,boolean directed){
		assert n>=0;
		this.n=n;
		this.m=0;
		this.directed=directed;
		//g初始化为n个空的vector,表示每一个g[i]都为空,即没有任何边
		g=(Vector<Integer>[])new Vector[n];
		for(int i=0;i<n;i++)
			g[i]=new Vector<Integer>();
		
		
	}
	
	//返回节点个数
	public int V(){
		return n;
	}
	
	//返回边的个数
	public int E(){
		return m;
	}
	
	//向图中添加一个
	public void addEdge(int v,int w){
		
		assert v>=0 && v<n;
		assert w>=0 && w<n;
		
		g[v].add(w);
		if(v!=w && ! directed)
			g[w].add(v);
		
		m++;
	}
	
	//验证图中是否从v到w的边
	boolean hasEdge(int v,int w){
		
		assert v>=0 && v<n;
		assert w>=0 && w<n;
		
		for(int i=0;i<g[v].size();i++)
			if(g[v].elementAt(i)==w)
				return true;
		
		return false;
	}
	
	//返回图中一个顶点的所有邻边
	//由于java使用引用机制,返回一个Vector不会带来额外开销
	public Iterable<Integer> adj(int v){
		assert v>=0 && v<n;
		return g[v];
	}
	
	
}

 

稠密图    -邻接矩阵

这个n个节点的二维数组

n*n

0 1 2 3 这个是节点对应的

0和1连接 说明 在1的下面就是1 为真 连接

1和 2 3 0 都连接  那么 0 2 3都为1

2 和1 3连接 那么 1的连接

 

有向矩阵

和有向表差不多

 

package com.binglian.Graph;

import java.util.Vector;

//稠密图	-邻接矩阵
public class DenseGraph {

	private int n;//节点数
	private int m;//边数
	private boolean directed;//是否为有向图
	private boolean[][] g;//图的具体数据
	
	//构造函数
	public DenseGraph(int n,boolean directed){
		assert n>=0;//断言
		this.n=n;
		this.m=0;//初始化没有边
		this.directed=directed;
		//g初始化为n*n的布尔矩阵,每一个g[i][j]均为false,表示为没有任何边
		//false为boolean型的默认值;
		g=new boolean[n][n];
	}
	
	//返回节点个数
	public int V(){
		return n;
	}
	
	//返回边的个数
	public int E(){
		return m;
	}
	
	
	//向图中添加一个边
	public void addEdge(int v,int w){
		assert v >= 0 && v < n ;
        assert w >= 0 && w < n ;
        
        if(hasEdge(v,w))
        	return ;
	
        g[v][w]=true;
        if(!directed)
        	g[w][v]=true;//如果是无向图的话 需要在相互连接
        
        m++;
	}
	
	//返回图中一个顶点的所有邻边
	//由于java1使用引用机制,返回一个Vector不会带来额外开销
	public Iterable<Integer> adj(int v){
		assert v>=0 && v<n;
		Vector<Integer> adjv=new Vector<Integer>();
		for(int i=0;i<n;i++)
			if(g[v][i])
				adjv.add(i);
		return adjv;
	}
	
	
	//验证图中是否从v到w的边
	boolean hasEdge(int v,int w){
		assert v>=0 && v<n;
		assert w>=0 && w<n;
		return g[v][w];
	}
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值