图存储结构

123 阅读1分钟

1 邻接矩阵

使用二维数组存储: 图的指向对应边数组为行数指向列数,数值为权值。

例如:1 --> 2,权值为3,则在边数组中a[1][2] = 3,其余位置填0。

如果不带权值的图,1 --> 2,则在边数组中a[1][2] = 1,其余位置填0。

graph TD
	1((1)) --9--> 0((0)) --6--> 4((4))
	1((1)) --3--> 2((2)) --5--> 3((3)) --1--> 4((4))
	2((2)) --2--> 0((0))
[0000690300200500000100000](边数组)\left[ \begin{matrix} 0 & 0 & 0 & 0 & 6 \\ 9 & 0 & 3 & 0 & 0 \\ 2 & 0 & 0 & 5 & 0 \\ 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 \\ \end{matrix} \right] \tag{边数组}

优点: 适合稠密图的存储;码量少;对边的存储、查询、更新等操作快而简单;只需要一步即可访问和修改

缺点: 空间复杂度太高,存储结点比较多的图会MLE(爆内存),存储稀疏图时空间浪费太大;一般情况下无法存储重边

2 邻接表

使用动态二维数组存储:

[402034] \left[ \begin{matrix} 4 \\ 0 & 2 \\ 0 & 3 \\ 4 \\ \\ \end{matrix} \right]

代码:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<vector<int> > v(5, vector<int>());
    v[0].push_back(4);
    
    v[1].push_back(0);
    v[1].push_back(2);
    
    v[2].push_back(0);
    v[2].push_back(3);
    
    v[3].push_back(4);
    
    return 0;
}

带权值的代码: 写一个结构体,push结构体到动态数组

struct Node {
    int v, len  // v:记录连接的点,len:权值
    Node(int v, int len) {
        this->v = v;
        this->len = len;
    }
};

优点: 存储效率非常高;空间复杂度优;可以存储重边

缺点: 码量较大;访问和修改会变慢