您的位置:首页 > 其它

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

2014-01-11 22:15 309 查看
#返回上一级

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

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

#返回上一级
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: