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

  #返回上一级

@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则是按从大到小的顺序”的要求,内层循环是按从大到小方向遍历的。

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

 #返回上一级 

原文地址:https://www.cnblogs.com/zhanghaiba/p/3515407.html