邻接表(Adjacency List)

简介(Introduction)

邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对于图的每个顶点建立一个容器( \(n\) 个顶点建立 \(n\) 个容器),第 \(i\) 个容器中的结点包含顶点 \(v_i\) 的所有邻接顶点。


描述(Description)

  • 通过 \(head\) 可以定位到每一类所构成的链表
  • 当需要插入新的节点时,可以通过 \(head\) 定位到新的数据节点所属类别的表头,然后进行 头插

示例(Example)

  • 邻接表存储有向图:
    image

  • 邻接表存储无向图:
    image

  • 例如:插入 \((1, 2), (2, 3),(2, 5),(3,6),(5,4),(5,1)\) 六条边后,邻接表的信息如下:
    image


代码(Code)

  • 写法一:
    const int N = 边数;
    
    int ve[N], we[N], ne[N], head[N], tot;
    
    // 加入有向边 x -> y ,权值为 z
    void add(int x, int y, int z) {
    	ve[++ tot] = y, we[tot] = z;  // 真实数据
    	ne[tot] = head[x], head[x] = tot;  // 在表头 x 处插入
    }
    
    // 遍历
    void print(int x) {
    	for (int i = head[x]; i; i = ne[i]) {
    		int j = ver[i], w = edge[i];  // 找到一条有向边(x, j), 权值为 w
    		// 具体逻辑
    		// printf("%d ", j);
    	}
    }
    

  • 写法二:
    const int N = 边数;
    
    int e[N], w[N], ne[N], h[N], idx;
    
    void add(int a, int b, int c) {  // 加边
    	e[idx] = b, w[idx] = c;
    	ne[idx] = h[a], h[a] = idx ++ ;
    }
    
    void print(int a) {  // 遍历
    	for (int i = h[a]; ~i; i = ne[i]) {
    		int j = e[i], w = w[i];  // 找到一条有向边(a, j), 权值为 w
    		// 具体逻辑
    		// printf("%d ", j);
    	}
    }
    

注:需要先 memset(h, -1, sizeof h);


  • \(vector\) 存储:
    const int N = 点数;
    
    struct Edge {
    	int to;  // 终点
    	int w;  // 边的权值
    };
    vector<edge>g[N];  // g[i] 中 i 表示起始位置
    
    void add(int from, int to, int c) {
    	Edge e = {to, c};
    	g[from].push_back(e);  // 向 vector 的最后添加一条边
    }
    
    // 遍历
    void print(int a) {
    	for (int i = 0; i < g[a].size(); i ++ )
    		// 具体逻辑
    		// printf("%d ", g[a][i].to);
    }
    

posted @ 2023-05-01 09:53  FFex  阅读(737)  评论(0编辑  收藏  举报