zoukankan      html  css  js  c++  java
  • 邻接表建图的三种方式的时空比较(解析+图示)

    邻接表建图法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:银志圆

  • 相关阅读:
    Linux下sed,awk,grep,cut,find学习笔记
    Python文件处理(1)
    KMP详解
    Java引用详解
    解决安卓中页脚被输入法顶起的问题
    解决swfupload上传控件文件名中文乱码问题 三种方法 flash及最新版本11.8.800.168
    null id in entry (don't flush the Session after an exception occurs)
    HQL中的Like查询需要注意的地方
    spring mvc controller间跳转 重定向 传参
    node to traverse cannot be null!
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8543163.html
Copyright © 2011-2022 走看看