zoukankan      html  css  js  c++  java
  • 邻接表怎么写

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

     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]);
    }
    

      

  • 相关阅读:
    单播、广播和多播IP地址
    nagios安装部署及详细配置说明(转)
    centos6.5下cacti部署说明
    HAproxy配置详解
    mysql全量和增量备份详解(带脚本)
    lvs原理及安装部署详解(参考)
    curl命令的用法
    mysql日志解析
    MySQL查看和修改表的存储引擎
    mysql备份和还原
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4185830.html
Copyright © 2011-2022 走看看