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

  #返回上一级

@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("\n");

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

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

 

 #返回上一级 

你可能感兴趣的:(转换)