• 邻接表建图的三种方式的时空比较(解析+图示)


    邻接表建图法1
    极大的节省了空间和时间 是建图非常棒的一种方式
    它利用数组模拟出边与边之间的关系  

    图示解析(数据为代码中的测试数据):

    复制代码
    1 #include<iostream>
    2  #define Maxn 200
    3  usingnamespace std;
    4  struct edge{int from,to,weight,next;}e[Maxn];//存储边信息的结构体 
    5 int first[Maxn];//起点为下标存储(e中边的位置) 
    6 int main()
    7 {
    8 int edges;//边数 
    9 memset(first,-1,sizeof(first));
    10 //因为刚开始first不指向任何一条边的下标,所以first都为-1 
    11 cin>>edges;//边数 
    12 for(int i=0;i<edges;i++)
    13 {
    14 cin>>e[i].from>>e[i].to>>e[i].weight;//起点 终点 权重 
    15 e[i].next=first[e[i].from];first[e[i].from]=i;//不容易理解的地方
    16 /*
    17 利用first数组存储的是最新的(以数组下标为起点的)边的下标 
    18 并且该条边的next指向的是同样以数组下标为起点的下一条边的下标 
    19 直到下一条边的next=-1(即将所有以数组下标为起点的边都遍历了一遍) 
    20 */
    21 }
    22 for(int u=1;u<10;u++)//输出图 
    23 {
    24 cout<<"以"<<u<<"为起点的所有边的信息:"<<endl; 
    25 for(int v=first[u];v!=-1;v=e[v].next)//遍历以u为起点的所有边的信息 
    26 cout<<e[v].from<<""<<e[v].to<<""<<e[v].weight<<endl;
    27 }
    28 return0;
    29 }
    30 /*
    31 5
    32 3 4 6
    33 3 7 8
    34 1 3 6
    35 2 4 7
    36 3 5 1
    37 */
    复制代码

    邻接表建图法2
    这种方式与上一种方式出自一个思想 
    只不过是前者是利用数组模拟边之间的关系
    而它是用指针来表示边之间的关系 

    复制代码
    1 #include<iostream>
    2 #define Maxn 200
    3 usingnamespace std;
    4 struct edge
    5 {
    6 int from,to,weight;
    7 edge *next;
    8 }e[Maxn];//存储边 
    9 edge*first[Maxn];//所有以起点为下标的头指针
    10 int main()
    11 {
    12 int edges;//边数 
    13 for(int i=0;i<Maxn;i++)first[i]=NULL;
    14 //因为刚开始first不指向任何一条边,所以初始化first都为NULL 
    15 cin>>edges;//边数 
    16 for(int i=0;i<edges;i++)
    17 {
    18 cin>>e[i].from>>e[i].to>>e[i].weight;//起点 终点 权重 
    19 e[i].next=first[e[i].from];first[e[i].from]=&e[i];//不容易理解的地方
    20 /*
    21 利用first数组存储的是最新的(以数组下标为起点的)边的地址 
    22 并且该条边的next指向的是同样以数组下标为起点的下一条边的地址 
    23 直到下一条边的next=NULL(即将所有以数组下标为起点的边都遍历了一遍) 
    24 */
    25 }
    26 for(int u=1;u<10;u++)//输出图 
    27 {
    28 cout<<"以"<<u<<"为起点的所有边的信息:"<<endl; 
    29 for(edge*v=first[u];v;v=v->next)//遍历所有以u为起点的边 
    30 cout<<v->from<<""<<v->to<<""<<v->weight<<endl;
    31 }
    32 return0;
    33 }
    复制代码

    邻接表建图3 
    这种方式十分精巧,适合表明点之间的关联关系,并且可以统计出以某一点为起点的边的总数
    但不能够存储权重,如果数据量比较大时,浪费的空间非常大 

    复制代码
    1 #include<iostream>
    2 #define Maxn 200
    3 usingnamespace std;
    4 int main()
    5 {
    6 int G[Maxn][Maxn],edges,from;
    7 for(int u=1;u<Maxn;u++)G[u][0]=0; //G[u][0]用于记录起点为u的边的总数 
    8 cin>>edges;//边数 
    9 while(edges--)
    10 cin>>from>>G[from][++G[from][0]];//起点 终点 
    11 for(int u=1;u<10;u++)//输出图 
    12 {
    13 cout<<"所有以"<<u<<"为起点的边共有"<<G[u][0]<<"条分别为: "<<endl; 
    14 for(int v=1;v<=G[u][0];v++)//输出所有以u为起点的边的信息 
    15 cout<<G[u][v]<<"";
    16 cout<<" ";
    17 }
    18 return0;
    19 }
    复制代码

    Author:银志圆

  • 相关阅读:
    Mali 水题
    树状数组求区间最值
    POJ1125 Stockbroker Grapevine 最短路
    jquery radio取值,checkbox取值,select取值 及选中(引用)
    过滤注入代码的存储过程
    怎么进行项目管理
    现在已经不喜欢注释而喜欢直接看代码了
    风潮唱片总目录及下载地址2009年2月9日更新
    什么时候用存储过程
    sql server 外键 更新(删除)规则
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8543163.html
Copyright © 2020-2023  润新知