• 图的常用存储结构


    一、邻接矩阵

      邻接矩阵是简单的也是比较常用的一种表示图的数据结构,对于一个有N个点的图,需要一个N*N的矩阵,这个矩阵的i行第j列的数值表示点vi到点vj的距离。邻接矩阵需要初始化,map[i][i] = 0;map[i][j] = INF(i != j),对于每组读入的数据vi,vj,w(vi为边的起点,vj为边的终点,w为边的权值),赋值map[vi][vj] = w,另外邻接矩阵的值和边的输入顺序无关。

      对于邻接矩阵来说,初始化需要O(n^2)的时间,建图需要O(m),所以总时间复杂度是O(n^2),空间上,邻接矩阵的开销也是O(n^2),和点的个数有关。

    二、前向星

      前向星是一种通过存储边的方式来存储图的数据结构。构造的时候,只需要读入每条边的信息,将边存放在数组中,把数组中的边按照起点顺序排序,前向星就构造完毕,为了查询方便,经常会有一个数组存储起点为vi的第一条边的位置.

      由于涉及排序,前向星的构造时间复杂度与排序算法有关,一般情况下时间复杂度为O(mlogN),空间上需要两个数组,所以空间复杂度为O(m + n),有点在于可以应对点非常多的情况,可以存储重边,但是不能直接判断任意两个顶点之间是否有边.

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <algorithm>
     7 using namespace std;
     8 typedef long long LL;
     9 
    10 const int MAXN = 1000 + 3;
    11 int head[MAXN]; //存储起点为Vi的边第一次出现的位置
    12 
    13 struct NODE
    14 {
    15     int from;
    16     int to;
    17     int w;
    18 };
    19 NODE edge[MAXN];
    20 
    21 bool cmp(NODE a, NODE b)
    22 {
    23     if(a.from == b.from && a.to == b.to) return a.w < b.w;
    24     if(a.from == b.from) return a.to < b.to;
    25     return a.from < b.from;
    26 }
    27 
    28 int main()
    29 {
    30     freopen("input.txt", "r", stdin);
    31     int n,m;
    32     cin >> n >> m;
    33     for(int i = 0; i < m; i++)
    34     {
    35         cin >> edge[i].from >> edge[i].to >> edge[i].w;
    36     }
    37     sort(edge, edge + m, cmp);
    38     memset(head, -1, sizeof(head));
    39     head[edge[0].from] = 0;
    40     for(int i = 1; i < m; i++)
    41     {
    42         if(edge[i].from != edge[i - 1].from)
    43         {
    44             head[edge[i].from] = i;
    45         }
    46     }
    47     for(int i = 1; i <= n; i++)
    48     {
    49         for(int k = head[i]; edge[k].from == i && k < m; k++)
    50         {
    51             cout << edge[k].from << ' ' << edge[k].to << ' ' << edge[k].w <<endl;
    52         }
    53     }
    54     for(int i = 0; i <= n; i++)
    55     {
    56         cout << head[i] << " ";
    57     }
    58     cout << endl;
    59     return 0;
    60 }

    三、链式前向星

      链式前向星采用数组模拟链表的方式实现邻接表的功能,并且使用很少的额外空间,是当前建图和遍历效率最高的存储方式.数组模拟链表的主要方式是记录下一个节点的数组的在哪一个位置。head数组存储描述点vi边信息的链的起点在Edges数组的位置。构造链式前向星就是将新加入的节点链对应链的最开始并修改head数组的对应位置的值.

      链式前向星的建图时间复杂度为O(m),空间上为O(m + n)。

     1 //链式前向星
     2 const int maxN = 100 + 3;
     3 const int maxM = 1000 + 3;
     4 int head[maxN];
     5 int N, M;
     6 
     7 struct EdgeNode
     8 {
     9     int to;   //边的后继
    10     int w;    //权值
    11     int next;     //指向下一条边的位置
    12 };
    13 EdgeNode Edges[maxM];
    14 
    15 int main()
    16 {
    17     //freopen("input.txt", "r", stdin);
    18     memset(head, -1, sizeof(head));
    19     cin >> N >> M;  //N个点,M条边
    20     for(int i = 1; i <= M; i++)
    21     {
    22         int x, y ,z;
    23         cin >> x >> y >> z;
    24         Edges[i].to = y;
    25         Edges[i].w = z;
    26         Edges[i].next = head[x];
    27         head[x] = i;
    28     }
    29     return 0;
    30 }
    31 
    32 void traversal()
    33 {
    34     for(int i = 1; i <= N; i++)
    35     {
    36         for(int k = head[i]; k != -1; k = Edges[k].next)
    37         {
    38             cout << i << ' ' << Edges[k].to << ' ' << Edges[k].w << endl;
    39         }
    40     }
    41 }
  • 相关阅读:
    连通域标记
    qt&gdal
    gdal vs2013编译
    java配置
    windows下面安装Python和pip
    mfc operator new”: 没有重载函数接受 3 个参数
    std::min&std::max与mfc冲突问题
    qt中vtk易出现错误
    cmake构建qt工程
    Webstorm补丁
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5397941.html
Copyright © 2020-2023  润新知