邻接表和邻接矩阵的相互转换
2014-01-11 22:15
309 查看
#返回上一级
@Author: 张海拔
@Update: 2014-01-11
@Link: http://www.cnblogs.com/zhanghaiba/p/3515407.html
这里是针对有向图,而且忽略掉顶点的数据(如名字等),输入的边(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则是按从大到小的顺序”的要求,内层循环是按从大到小方向遍历的。
另外把头插法函数(创建邻接表函数的核心)单独写成一个函数,满足小即是美的设计。在这里的转换函数中更是得到了复用。
#返回上一级
@Author: 张海拔
@Update: 2014-01-11
@Link: http://www.cnblogs.com/zhanghaiba/p/3515407.html
/* *Author: ZhangHaiba *Date: 2014-1-11 *File: mutual_conversion_adj_list_adj_mat.c * *a demo shows mutual conversion between adjacency list and adjacency matrix */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 512 typedef struct e_node* link; typedef struct e_node { int adjv; link next; }e_node; typedef struct v_node { int item; link next; }v_node; //public void init_adj_list(v_node*, int); void create_adj_list(v_node*, int, int); void show_adj_list(v_node*, int); void destory_adj_list(v_node*, int); void set_adj_mat(int); void show_adj_mat(int); void adj_mat_to_adj_list(v_node*, int); void adj_list_to_adj_mat(v_node*, int); //private static link head_insert_node(link, int); v_node list ; int mat ; int main(void) { int n, m; //create adj_list, then convert adj_list into adj_mat scanf("%d%d", &n, &m); init_adj_list(list, n); memset(mat, 0, sizeof mat); create_adj_list(list, n, m); adj_list_to_adj_mat(list, n); show_adj_mat(n); destory_adj_list(list, n); //create adj_list, then convert adj_mat into adj_list scanf("%d", &n); memset(mat, 0, sizeof mat); init_adj_list(list, n); set_adj_mat(n); adj_mat_to_adj_list(list, n); show_adj_list(list, n); destory_adj_list(list, n); return 0; } void init_adj_list(v_node* a, int n) { int i; for (i = 0; i < n; ++i) a[i].next = NULL; } link head_insert_node(link h, int v) { link p = malloc(sizeof (e_node)); p->adjv = v; link save = h; h = p; p->next = save; return h; } //for undirected graph void create_adj_list(v_node* a, int n, int m) { //input edge info: (x, y) int i, x, y; for (i = 0; i < m; ++i) { scanf("%d%d", &x, &y); a[x].next = head_insert_node(a[x].next, y); } } void show_adj_list(v_node* a, int n) { int i; link p; for (i = 0; i < n; ++i) { printf("%d", i); for (p = a[i].next; p != NULL; p = p->next) printf("->%d", p->adjv); printf("\n"); } } void destory_adj_list(v_node* a, int n) { int i; link p; for (i = 0; i < n; ++i) for (p = a[i].next; p != NULL; p = p->next) free(p); } void set_adj_mat(int n) { int i, j; for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) scanf("%d", &mat[i][j]); } void show_adj_mat(int n) { int i, j; for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) printf(j == n-1 ? "%d\n" : "%d ", mat[i][j]); } void adj_mat_to_adj_list(v_node* a, int n) { int i, j; for (i = 0; i < n; ++i) for (j = n-1; j > -1; --j) if (mat[i][j] > 0) a[i].next = head_insert_node(a[i].next, j); } void adj_list_to_adj_mat(v_node* a, int n) { int i; link p; for (i = 0; i < n; ++i) { for (p = a[i].next; p != NULL; p = p->next) mat[i][p->adjv] = 1; } }
这里是针对有向图,而且忽略掉顶点的数据(如名字等),输入的边(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则是按从大到小的顺序”的要求,内层循环是按从大到小方向遍历的。
另外把头插法函数(创建邻接表函数的核心)单独写成一个函数,满足小即是美的设计。在这里的转换函数中更是得到了复用。
#返回上一级
相关文章推荐
- 图的邻接矩阵和邻接表表示,及相互之间的转换
- 邻接表和邻接矩阵在深度遍历中的相互转换
- 邻接表转换为邻接矩阵
- 4000 [C++]图的邻接矩阵、邻接表及其相互转化和邻接表的广度遍历、深度遍历
- 数据结构 图的邻接表表示转换成邻接矩阵表示的算法
- w_chart*(LPTSTR)和char*相互转换
- 【HDU 1874 2544 2066 2112】 Dijkstra单源最短路径专题 —— 优先队列+邻接表/邻接矩阵
- 地理坐标系与瓦片坐标系相互转换
- JAVA各种进制间的相互转换
- 字节流与位流的相互转换实现
- java中Data和String之间的相互转换
- java日期与字符串相互转换
- JS:字符串和数字之间的相互转换
- 解析JSON对象与字符串之间的相互转换
- LPTSTR CString 相互转换 CString char * 相互转换
- 字符串和编码而成的字节序列相互转换
- 新浪微博地址url字符与mid的相互转换算法及原理
- 本地时间与格林威治时间相互转换
- 火星坐标与地球坐标之间的相互转换的工具类
- QString和String相互转换