图的几种储存结构

来源:互联网 发布:页游服务端源码 编辑:程序博客网 时间:2024/06/06 03:31

昨天借了两本图论的书,
才发现我之前的做法有点笨,
一点优化都没有..
于是把一上午看的图的储存结构写了一边.
各种结构的优缺点总结了一下.
收获很大.

//图的几种储存结构
//1.邻接矩阵
//2.前向星(三元组)
//3.邻接表
//4.静态链表(链式前向星)

#define fence puts("----------------------")#define mem(a,b) memset(a,b,sizeof(a))#include <iostream>#include <cstring>#include <vector>#include <algorithm>#include <list>using namespace std;const int MAXN = 1010;const int INF = 0x3f3f3f3f;//图的几种储存结构//1.邻接矩阵//2.前向星(三元组)//3.邻接表//4.静态链表(链式前向星)//1.邻接矩阵//构造 时间复杂度O(n^2) 空间复杂度O(n^2)//优点:实现简单,可以直接查询任意两节点间是否存在边,和边的权值//缺点:遍历效率低,不能储存重边;初始化效率低;大图空间开销大(n>10e5);对于稀疏矩阵利用率低int n, m;//节点数,边数int Adjacency_matrix[MAXN][MAXN];void transam(){    for (int i = 0; i < n; ++i) {        for (int j = 0; j < n; ++j)            cout << Adjacency_matrix[i][j] << " ";        cout << endl;    }}void ini_Am(){    //int n, m;//节点数,边数    cin >> n >> m;    mem(Adjacency_matrix, INF);    for (int i = 0; i < n; ++i)        Adjacency_matrix[i][i] = 0;    for (int i = 0; i < m; ++i)    {        int x, y, z;//节点,节点,路径长度        cin >> x >> y >> z;        Adjacency_matrix[x][y] = Adjacency_matrix[y][x] = z;    }    fence;    transam();    fence;}//2.前向星(三元组)//构造 时间复杂度O(mlogm) 空间复杂度O(m)//优点:可以储存重边,复杂度低//缺点:无法直接判断两点间是否存在边struct Node {    int x, y, z;    Node(int X, int Y, int Z) :x(X), y(Y), z(Z) {   }};//排序规则 按照x有小到大排序,若x相等按y小大顺序排,若y也相等,按z小大顺序排bool cmp(Node a, Node b){    if (a.x == b.x && a.y == b.y)        return a.z < b.z;    if (a.x == b.x)        return a.y < b.y;    return a.x < b.x;}vector<Node>edge;void transtri(){    int len = edge.size();    for (int i = 0; i < len; ++i)        cout << edge[i].x << " " << edge[i].y << " " << edge[i].z << endl;}void ini_tri(){    //int n, m;//节点数,边数    cin >> n >> m;    for (int i = 0; i < m; ++i)    {        int x, y, z;//节点,节点,路径长度        cin >> x >> y >> z;        edge.push_back(Node(x, y, z));    }    sort(edge.begin(), edge.end(), cmp);    fence;    transtri();    fence;}//3.邻接表//构造 时间复杂度O(m) 空间复杂度O(m)//优点:复杂度低//缺点:无法直接判断两点间是否存在边vector<vector<pair<int, int>>>vec;void transedg(){    for (int i = 0; i < n; ++i)        for (int j = 0; j < vec[i].size(); ++j)            cout << i << " " << vec[i][j].first << " " << vec[i][j].second << endl;}void ini_edg(){    //int n, m;//节点数,边数    cin >> n >> m;    vec.resize(m);    for (int i = 0; i < m; ++i)    {        int x, y, z;//节点,节点,路径长度        cin >> x >> y >> z;        vec[x].push_back(pair<int, int>(y, z));    }    fence;    transedg();    fence;}//4.链式前向星//时间复杂度 O(m) 空间复杂度O(n+m)//优点:代码原理简单;可以储存重边;可以储存大量数据;没有动态内存管理;//缺点:无法直接判断两点间是否存在边struct EdgeNode{    int to;    int w;    int next;}Edges[MAXN];int Head[MAXN];void trans(){    for (int i = 0; i < n; ++i)        for (int k = Head[i]; k != -1; k = Edges[k].next)            cout << i << " " << Edges[k].to << " " << Edges[k].w << endl;}void ini_edg2(){    //int n, m;//节点数,边数    cin >> n >> m;    for (int i = 0; i < n; ++i)        Head[i] = -1;    for (int i = 0; i < m; ++i)    {        int x, y, z;//节点,节点,路径长度        cin >> x >> y >> z;        Edges[i].to = y;        Edges[i].w = z;        Edges[i].next = Head[x];        Head[x] = i;    }    fence;    trans();    fence;}/*//测试数据3 40 1 10 2 21 2 30 2 4*/int main(){    ini_Am();    ini_tri();    ini_edg();    ini_edg2();    system("pause");    return 0;}