• 邻接表和邻接矩阵的相互转换


      #返回上一级

    @Author: 张海拔

    @Update: 2014-01-11

    @Link: http://www.cnblogs.com/zhanghaiba/p/3515407.html

      1 /*
      2  *Author: ZhangHaiba
      3  *Date: 2014-1-11
      4  *File: mutual_conversion_adj_list_adj_mat.c
      5  *
      6  *a demo shows mutual conversion between adjacency list and adjacency matrix
      7  */
      8 
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 #include <string.h>
     12 #define N 512
     13 typedef struct e_node* link;
     14 
     15 typedef struct e_node {
     16     int adjv;
     17     link next;
     18 }e_node;
     19 
     20 typedef struct v_node {
     21     int item;
     22     link next;
     23 }v_node;
     24 
     25 //public
     26 void init_adj_list(v_node*, int);
     27 void create_adj_list(v_node*, int, int);
     28 void show_adj_list(v_node*, int);
     29 void destory_adj_list(v_node*, int);
     30 void set_adj_mat(int);
     31 void show_adj_mat(int);
     32 void adj_mat_to_adj_list(v_node*, int);
     33 void adj_list_to_adj_mat(v_node*, int);
     34 //private
     35 static link head_insert_node(link, int);
     36 
     37 v_node list[N];
     38 int mat[N][N];
     39 
     40 int main(void)
     41 {
     42     int n, m;
     43 
     44     //create adj_list, then convert adj_list into adj_mat
     45     scanf("%d%d", &n, &m);
     46     init_adj_list(list, n);
     47     memset(mat, 0, sizeof mat);
     48     create_adj_list(list, n, m);
     49     adj_list_to_adj_mat(list, n);
     50     show_adj_mat(n);
     51     destory_adj_list(list, n);
     52 
     53     //create adj_list, then convert adj_mat into adj_list
     54     scanf("%d", &n);
     55     memset(mat, 0, sizeof mat);
     56     init_adj_list(list, n);
     57     set_adj_mat(n);
     58     adj_mat_to_adj_list(list, n);
     59     show_adj_list(list, n);
     60     destory_adj_list(list, n);
     61     return 0;
     62 }
     63 
     64 void init_adj_list(v_node* a, int n)
     65 {
     66     int i;
     67     
     68     for (i = 0; i < n; ++i)
     69         a[i].next = NULL;
     70 }
     71 
     72 link head_insert_node(link h, int v)
     73 {
     74     link p = malloc(sizeof (e_node));
     75     p->adjv = v;
     76     link save = h;
     77     h = p;
     78     p->next = save;
     79     return h;
     80 }
     81 
     82 //for undirected graph
     83 void create_adj_list(v_node* a, int n, int m)
     84 {
     85     //input edge info: (x, y)
     86     int i, x, y;
     87     
     88     for (i = 0; i < m; ++i) {
     89         scanf("%d%d", &x, &y);
     90         a[x].next = head_insert_node(a[x].next, y);
     91     }
     92 }
     93 
     94 void show_adj_list(v_node* a, int n)
     95 {
     96     int i;
     97     link p;
     98     
     99     for (i = 0; i < n; ++i) {
    100         printf("%d", i);
    101         for (p = a[i].next; p != NULL; p = p->next)
    102             printf("->%d", p->adjv);
    103         printf("
    ");
    104     }
    105 }
    106 
    107 void destory_adj_list(v_node* a, int n)
    108 {
    109     int i;
    110     link p;
    111     
    112     for (i = 0; i < n; ++i)
    113         for (p = a[i].next; p != NULL; p = p->next)
    114             free(p);
    115 }
    116 
    117 void set_adj_mat(int n)
    118 {
    119     int i, j;
    120     
    121     for (i = 0; i < n; ++i)
    122         for (j = 0; j < n; ++j)
    123             scanf("%d", &mat[i][j]);
    124 }
    125 
    126 void show_adj_mat(int n)
    127 {
    128     int i, j;
    129 
    130     for (i = 0; i < n; ++i)
    131         for (j = 0; j < n; ++j)
    132             printf(j == n-1 ? "%d
    " : "%d ", mat[i][j]);
    133 }
    134 
    135 void adj_mat_to_adj_list(v_node* a, int n)
    136 {
    137     int i, j;
    138     
    139     for (i = 0; i < n; ++i)
    140         for (j = n-1; j > -1; --j)
    141             if (mat[i][j] > 0)
    142                 a[i].next = head_insert_node(a[i].next, j);
    143 }
    144 
    145 void adj_list_to_adj_mat(v_node* a, int n)
    146 {
    147     int i;
    148     link p;
    149     
    150     for (i = 0; i < n; ++i) {
    151         for (p = a[i].next; p != NULL; p = p->next)
    152             mat[i][p->adjv] = 1;
    153     }
    154 }

    这里是针对有向图,而且忽略掉顶点的数据(如名字等),输入的边(x,y),x是按从小到大的顺序,同个x对应的y则是按从大到小的顺序。

    测试用例

    输入:

    5 6
    0 4
    1 2
    1 0
    2 3
    2 0
    3 4

    5
    0 0 0 0 1
    1 0 1 0 0
    1 0 0 1 0
    0 0 0 0 1
    0 0 0 0 0

    输出:

    0 0 0 0 1
    1 0 1 0 0
    1 0 0 1 0
    0 0 0 0 1
    0 0 0 0 0

    0->4
    1->0->2
    2->0->3
    3->4
    4

    可以看到,如果熟悉邻接表的创建,这种相互转换是很容易的。

    注意矩阵转邻接表时,为了满足上述“输入的边(x,y),x是按从小到大的顺序,同个x对应的y则是按从大到小的顺序”的要求,内层循环是按从大到小方向遍历的。

    另外把头插法函数(创建邻接表函数的核心)单独写成一个函数,满足小即是美的设计。在这里的转换函数中更是得到了复用。

     #返回上一级 

  • 相关阅读:
    单选文本及多行文本溢出问题
    div和textarea内容转换(****)
    URL OR PC/PHONE OR Strlen
    DocumentFragment(创建文档碎片节点)
    ETag
    重绘和回流
    自定义指令
    Angular JS 自定义服务
    jquery ajax 实例
    js 斐波那契序列
  • 原文地址:https://www.cnblogs.com/zhanghaiba/p/3515407.html
Copyright © 2020-2023  润新知