• 【转】图的邻接链表 adjacent list of graph


    http://hi.baidu.com/fly_fireocean/item/0711568aa52f1acf99255ffc

    邻接链表(Adjacency List)是图的一种链式存储结构,与树型结构中的孩子链表相似。通常邻接链表也称邻接表。

    1. 邻接表的结点结构
    边结点结构

         邻接表中每个表结点均有两个域:
     ① 邻接点域adjvex
      存放与vi相邻接的顶点vj的序号j。
     ② 链域next
      将邻接表的所有表结点链在一起。
    注意:
         如果带权图,则在表结点中还应增加一个保存权值等相关信息info。

    2.邻接表的表示
         对于无向图,vi的邻接表中每个表结点都对应于与vi相关联的一条边。因此,将邻接表的表头向量称为顶点表。将无向图的邻接表称为边表。
    注意:
        n个顶点e条边的无向图的邻接表表示中有n个顶点表结点和2e个边表结点。
         对于有向图,vi的邻接表中每个表结点都对应于以vi为始点射出的一条边。因此,将有向图的邻接表称为出边表。
    注意:
        n个顶点e条边的有向图,它的邻接表表示中有n个顶点表结点和e个边表结点。

    4.有向图的逆邻接表
        在有向图中,为图中每个顶点vi建立一个入边表的方法称逆邻接表表示法。
        入边表中的每个表结点均对应一条以vi为终点(即射入vi)的边。
    【例】


    注意:
         n个顶点e条边的有向图,它的接表表示中有n个顶点表结点和e个边表结点。

    邻接链表表示的图类 
    const int MaxVertices=100;
    typedef int VerT;
    typedef int DistT;
    struct Edge{ int dest; //邻接顶点下标
                    DistT weight; //边的权值,或更多
                    Edge *next; //指针
                 };
    struct item { VerT data;       //顶点数据
                    Edge *adj;     //邻接边的指针
                 };
    item Vertices[MaxVertices];       //顶点的数组 

    建立一个无向图的邻接链表:
    void AdjTWGraph::CreatG(int n,int e)
    { int vi,vj; DistT w;
    numE=e; numV=n;
    cout<<"\n 输入顶点的信息(整型):" ;
    for (int i=1; i<=numV; i++ ) { cout<<"\n "<<i<<": ";
    cin>>Vertices[i].data;
    }
    for ( int i=1; i<=numE; i++ )
    { cout<<"\n 输入边的信息(顶点号vi 顶点号vj 边的权值W):";
    cin>>vi>>vj>>w;
    //---------------------- 在第vi条链表上,链入边(vi,vj)的结点
    Edge *q=new Edge;
    q->dest=vj; q->weight=w; q->next=NULL; 
    //vj是vi的邻接顶点,w是权值
    if(Vertices[vi].adj==NULL) Vertices[vi].adj=q;           //第一次插入
    else            //非第一次插入
    { Edge *curr=Vertices[vi].adj, *pre=NULL;
    while (curr!=NULL && curr->dest<vj )
    { pre=curr; curr=curr->next; }
    if ( pre==NULL )           //在第一个结点前插入
    { q->next=Vertices[vi].adj; Vertices[vi].adj=q; }
    else {q->next=pre->next;           //在其他位置插入
    pre->next=q;
    }
    }
    //-------------------在第vj条链表上,链入边(vj,vi)的结点
    Edge *p=new Edge;
    p->dest=vi; p->weight=w; p->next=NULL;
    if(Vertices[vj].adj==NULL) Vertices[vj].adj=p;           //第一次插入
    else            //非第一次插入
    { Edge *curr=Vertices[vj].adj, *pre=NULL;
    while (curr!=NULL && curr->dest<vi )
    { pre=curr; curr=curr->next; }
    if ( pre==NULL )           //在第一个结点前插入
    { p->next=Vertices[vj].adj; Vertices[vj].adj=p; }
    else { p->next=pre->next;           //在其他位置插入
    pre->next=p;
    }
    }
    }       //for ( int i=1; i<=numE; i++ )
    }            //函数结束
          该算法的时间复杂度是 O(n+2e) ,在上述算法中去掉黑体部分语句,就是有向图的建立算法,其时间复杂度为 O(n+e) 

  • 相关阅读:
    Elasticsearch入门系列(一)
    清楚Chrome缓存
    解决IIS启动站点报错
    Input type="file"上传文件change事件只触发一次解决方案
    本地计算机上的XXX服务启动后停止,某些服务在未由其它服务或程序使用时将自动停止
    SQL Server Datetime类型为NULL不能用ISNULL(datetime,' ')来判断,会导致1900-01-01
    浏览指南
    谁发明的c++
    c++的用处
    不一样的二叉树遍历(小学生都会)
  • 原文地址:https://www.cnblogs.com/mfryf/p/2722843.html
Copyright © 2020-2023  润新知