• 邻接表怎么写


      数据结构书上表示邻接表比较复杂,一般形式如下:

     1 struct ArcNode{            //边结点
     2     int adjvex;            //有向边的另一个邻接点的序号
     3     ArcNode *nextarc;    //指向下一个边结点的指针
     4 };
     5 
     6 struct VNode {            //顶点
     7     int data;            //顶点信息
     8     ArcNode *head1;        //出边表的表头指针
     9     ArcNode *head2;        //入边表的表头指针
    10 };
    11 
    12 struct LGraph{            //图的邻接表储存结构
    13     VNode vertes[MAXN];    //顶点数组
    14     int vexnum,arcnum;    //顶点数和边(弧)数
    15 };
    16 LGraph lg;                //图(邻接表存储)

     输入n,m分别为图的顶点数目和边数

    接下来m行输入分表输入一条边的起点和终点

    输出每个顶点的出度和入度

      1 #include "iostream"
      2 #include "algorithm"
      3 #include "memory.h"
      4 #include "cmath"
      5 using namespace std;
      6 #define MAXN 111
      7 
      8 
      9 struct ArcNode{            //边结点
     10     int adjvex;            //有向边的另一个邻接点的序号
     11     ArcNode *nextarc;    //指向下一个边结点的指针
     12 };
     13 
     14 struct VNode {            //顶点
     15     int data;            //顶点信息
     16     ArcNode *head1;        //出边表的表头指针
     17     ArcNode *head2;        //入边表的表头指针
     18 };
     19 
     20 struct LGraph{            //图的邻接表储存结构
     21     VNode vertes[MAXN];    //顶点数组
     22     int vexnum,arcnum;    //顶点数和边(弧)数
     23 };
     24 LGraph lg;                //图(邻接表存储)
     25 
     26 
     27 void CreateLG()                                    //采用邻接表存储表示,构造有向图G
     28 {                                                
     29     int i = 0;                                    //循环变量
     30     ArcNode  *pi;                                //用来构造边链表的边结点指针
     31     int v1,v2;                                    //有向边的两个顶点
     32     //lg.vexnum = lg.arcnum = 0;                    
     33     //scanf("%d%d",&lg.vexnum,&lg.arcnum);
     34     for (int i = 0;i < lg.vexnum; ++ i)            //初始化表头指针为空
     35         lg.vertes[i].head1 = lg.vertes[i].head2 = NULL;
     36     for (int i = 0;i < lg.arcnum; ++ i) 
     37     {
     38         scanf("%d%d",&v1,&v2);                    //输入一条边的起点和终点
     39         v1--,v2--;
     40         pi = new ArcNode;
     41         pi -> adjvex = v2;
     42         pi -> nextarc = lg.vertes[v1].head1;    //插入链表
     43         lg.vertes[v1].head1 = pi;
     44         pi = new ArcNode;
     45         pi -> adjvex = v1;
     46         pi -> nextarc = lg.vertes[v2].head2;    //插入链表
     47         lg.vertes[v2].head2 = pi;
     48     }//end of for
     49 }//end of CreateLG
     50 
     51 void DeleteLG()
     52 {
     53     int i;
     54     ArcNode *pi;
     55     for (i = 0;i < lg.vexnum; ++ i)
     56     {
     57         pi = lg.vertes[i].head1;
     58         while (pi != NULL)
     59         {
     60             lg.vertes[i].head1 = pi -> nextarc;
     61             delete pi;
     62             pi = lg.vertes[i].head1;
     63         }
     64         pi = lg.vertes[i].head2;
     65         //释放第i个顶点去边表各边结点所占的存储空间
     66         while( pi != NULL) 
     67         {
     68             lg.vertes[i].head2 = pi->nextarc;
     69             delete pi;
     70             pi = lg.vertes[i].head2;
     71         }
     72     }
     73 }
     74 
     75 
     76 int main()
     77 {
     78     int i;                                        //循环变量
     79     int id,od;                                    //顶点的入度和出度
     80     ArcNode *pi;                                //用来遍历边链表的边结点指针
     81     while (1)
     82     {
     83         lg.vexnum = lg.arcnum = 0;
     84         scanf("%d%d",&lg.vexnum,&lg.arcnum);        
     85         //首先输入顶点个数和边数
     86         if (lg.vexnum == 0) break;                //输入数据结束
     87         CreateLG();                                //构造有向图的邻接表结构
     88         for (i = 0;i < lg.vexnum; ++ i)            //统计各顶点出度并输出
     89         {
     90             od = 0;
     91             pi = lg.vertes[i].head1;
     92             while (pi != NULL) 
     93             {
     94                 od++;
     95                 pi = pi -> nextarc;
     96             }
     97             if (i == 0) printf("%d",od);
     98             else printf(" %d",od);
     99         }
    100         puts("");
    101         for (i = 0;i < lg.vexnum; ++ i)            //统计各顶点入度并输出
    102         {
    103             id = 0;
    104             pi = lg.vertes[i].head2;
    105             while (pi != NULL)
    106             {
    107                 id++;
    108                 pi = pi -> nextarc;
    109             }
    110             if (i == 0 ) printf("%d",id);
    111             else printf(" %d",id);
    112         }
    113         puts("");
    114         DeleteLG();                                //释放
    115     }
    116     return 0;
    117 }
    完整程序

        其实有种简洁且高效的表示形式:

     1 typedef struct
     2 {
     3     int to;
     4     int w;
     5     int next;
     6 }Edge;
     7 Edge e[MAX];
     8 int pre[MAX];
     9 
    10 //初始化
    11 memset(pre,-1,sizeof(pre));
    12 
    13 //输入
    14 scanf("%d %d %d",&from,&to,&w1);
    15 e[i].to = to; e[i].w = w1; e[i].next = pre[from]; pre[from] = i;
    16 i++;
     

        上面这段代码中,边的结构体Edge由三个元素组成:弧头结点序号,边权值,下一条边的序号。e[i]指的是第i条边。pre[i]记录的是从当前输入的情况来看,序号为i的弧尾结点发出的第一条边的序号是pre[i]。

        这样,在操作某个结点发出的边时,可以像这么做:

    /*now为弧尾结点序号,i为now所发出的边序号,adj为弧头结点序号,w为now-->adj这条边的权值*/
    for(i = pre[now]; i != -1; i = edge[i].next)
    {
         int adj = edge[i].to;
         int w = edge
    
    [i].w;
         //do something...
    }
    

      

        其实,对于哈希表这类的存储结构(链表法解决冲突),与图的邻接表类似,也可以用类似的表示方法:

     1 typedef struct  
     2 {  
     3     char e[11];    //value  
     4     char f[11];     //key  
     5     int next;        //下一个结果(hash冲突)  
     6 }Entry;  
     7 Entry entry[M];  
     8 int hashIndex[M];   //哈希值为M的结果集的第一个在entry中的序号。  
     9   
    10 //输入:对key进行hash,  
    11 sscanf(str,"%s %s",entry[i].e,entry[i].f);  
    12 int hash = ELFHash(entry[i].f);  
    13 entry[i].next = hashIndex[hash];  
    14 hashIndex[hash] = i;  
    15 i++;  
    16   
    17 //使用:  
    18 for(int k = hashIndex[hash]; k; k = entry[k].next)  
    19 {  
    20     //do something..  
    21 }  

    以上转自http://yzmduncan.iteye.com/blog/883903

    vector建立邻接表

    建表
    vetcor<int> G[maxn];
    
    插入元素
    void Insert()
    {
    	G[a].pushback(b);
    }
    
    遍历元素
    void dfs()
    {
    	for (int i = 0;i < G[u].size();++ i)
    		dfs(G[u][i]);
    }
    

      

  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4185830.html
Copyright © 2020-2023  润新知