屯了几年的老草稿,今天看竟然忘了发出来
图的邻接表和邻接矩阵的相互转换是数据结构中最基本的技能之一。此题和1055:邻接矩阵到邻接表相反
题目描述
假设无向图G采用邻接表存储,编写一个算法输出邻接矩阵。
输入
第一行为一个整数n,表示顶点的个数(顶点编号为0到n-1)。第二行表示顶点0可直接到达的顶点编号,其他行定义相同。
输出
输出图G的邻接矩阵。整数矩阵大小为n*n,表示图的邻接关系。数字为0表示不邻接,1表示邻接。
样例输入
5
1 3 4
0 2 3
1 3 4
0 1 2 4
0 2 3
样例输出
01011
10110
01011
11101
10110
解题时可能遇到的细节问题
-
领接表的初始化
我们在建立图的邻接表时,一定一定一定要养成对其进行初始化的好习惯。这是很基本也是大家很容易忽略的一点。比如将邻接表中的指针设为NULL,顶点数和边数设置为0,等等。 -
邻接表如何输入?
我采用的是使用一个char型变量temp来循环录入(二重循环),遇到空格就跳过录入下一个,遇到换行符则说明这一行录入结束了,break出内循环,录入下一行。当然也可以使用一个n*n的int型二维数组来录入。首先将数组元素均初始化为-1,然后使用双重循环录入,在转换的时候遇到-1跳过就ok了
AC代码
#include<stdio.h>
#include<stdlib.h>
//定义图
typedef struct edge
{
int point;//顶点编号
struct edge *next;//指向下一个邻接顶点的指针
}Edge;
typedef struct graph
{
int vertex;//图的顶点编号
Edge *adjpoint;//指向该点第一个邻接点的指针
}Graph;
int g[300][300],n;//定义邻接矩阵和顶点数
Graph *init(int y,Graph gra[300])//对领接表进行初始化
{
int ty=y,i=0;
while(ty--)
{
gra[ty].adjpoint=NULL;
gra[ty].vertex=ty;
}
return gra;
}
Edge *Greate(Edge *adjpoint,int temp)//建立邻接表
{
Edge *pr=adjpoint,*p=NULL;
p=(Edge*)malloc(sizeof(Edge));//对p分配内存
if(pr==NULL)//还没有记录邻接点
adjpoint=p; //注意嗷!!! 如果这里换为pr=p的话无法成功修改邻接表的值
else//已有
{
while(pr->next!=NULL)
pr=pr->next;
pr->next=p;
}
p->point=(temp-'0');
p->next=NULL;
return adjpoint;
}
void Trans(Graph gra[])
{
for(int i=0;i<n;i++)
{
Edge *pr=gra[i].adjpoint;
if(pr==NULL)//如果这个领接表元素没有邻接点则continue
continue;
while(pr!=NULL)//领接表数组中元素逐个转换
{
g[i][pr->point]=1;//将对应位置修改为1
pr=pr->next;
}
}
}
int main()
{
scanf("%d",&n);
getchar();
Graph gra[300];
init(n,gra);//对领接表进行初始化
//以下部分是输入并创建领接表
for(int i=0;i<n;i++)
while(1)
{
char temp;
scanf("%c",&temp);
if(temp==' ')//遇到的是空格
continue;
if(temp=='\n')//到一行的末尾,则录入下一行
break;
gra[i].adjpoint=Greate(gra[i].adjpoint,temp);
}
//用自定义的Trans函数将邻接表转换为邻接矩阵
Trans(gra);
//下面是输出部分
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
printf("%d",g[i][j]);
printf("\n");
}
return 0;
}