图的实现

java实现

Posted by Starboyate on June 24, 2019

一、前言

记录下图的笔记


二、图

1.什么是图?

图(Graph)是由顶点的有穷非空集合和顶点之间的边的集合组成,通常 表示为: G(V,E)。其中,G 表示一个图,V 是图 G 中顶点的集合,E 是 图 G 中边的集合

2.图的分类

大致可以分为以下两类:
有向图和无向图
有权图和无权图


具体关于图的定义,可查看这里


3. 图的算法实现

无向图的实现主要有两种方式实现:
邻接矩阵 (密集图)
邻接表 (稀疏图)

邻接矩阵实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
 * 稠密图 - 邻接矩阵
 */
public class DenseGraph {
	/**
	 * 顶点
	 */
	private int n;
	/**
	 * 边数
	 */
	private int m;
	/**
	 * 图的具体数据
	 */
	private boolean[][] g;
	/**
	 * 是否为有向图
	 */
	private boolean isDirected;

	/**
	 * 初始化
	 * @param n
	 * @param isDirected
	 */
	public DenseGraph(int n, boolean isDirected) {
		this.n = n;
		this.m = 0;
		this.isDirected = isDirected;
		this.g = new boolean[n][n];
	}

	/**
	 * 返回顶点数
	 * @return
	 */
	public int V() {return this.n;}

	/**
	 * 返回边数
	 * @return
	 */
	public int E() {return this.m;}

	/**
	 * 向图中添加一个边
	 * @param v
	 * @param w
	 */
	public void addEdge(int v, int w) {
		// 如果存在这条边了,直接return
		if (hasEdge(v, w)) {
			return;
		}
		// 把第v 行 第 w 列 设置为 true,也就是代表这两个顶点已经存在边的连接
		g[v][w] = true;
		if (!isDirected) {
			// 也要相应的把第w 行 第 v 列 设置为 true,也就是代表这两个顶点已经存在边的连接
			g[w][v] = true;
		}
		m ++;
	}

	/**
	 * 判断是否已经存在这条边了
	 * @param v
	 * @param w
	 * @return
	 */
	public boolean hasEdge(int v, int w) {
		return g[v][w];
	}
		
}


邻接表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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 ;
        if (hasEdge(v, w))
        	return;
        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;
    }
}
4. 尾语

数据结构和算法永远是程序的灵魂、核心。所以,应该要掌握这些核心,才能让自己不被淘汰!加油!