在图论算法中图的表示主要有有邻接矩阵和邻接表两种表示法,在这篇文章之前,已经发布了dijkstra算法的邻接表表示法
dijkstra算法的邻接表表示
两种表示法的算法思路是一样的,只是表示的方式不同而带来了代码表示上的细微区别。个人认为邻接矩阵的表示法更为简洁,有邻接表有些繁琐。
由于思路相似,所以这里只记录代码上的区别;
首先在数据的输入上,以矩阵来储存图上各点的连通性
int map[9][9]={0};
for(i=0;i<9;i++)
{
printf("输入与第%d个点相连的点: ",i+1);
while(scanf("%d",&a)!=0)
{
map[i][a-1]=1; //如果相连,值为1。输入点为a,则在矩阵上的表示为a-1;
}
getchar();
}
由于我的测试数据是以非数字符号结束输入,所以不要忘记用getchar()来吞掉非数字符;
同样创建一个队列来控制各点的入队出队。
struct node{
int num;
pNode next;
};
pNode out(pNode head) //点出队
{
if(head->next==NULL)
{
free(head);
return NULL;
}
else{
pNode current=head->next;
free(head);
return current;
}
}
pNode add(pNode head,int a) //点入队
{
if(head==NULL)
{
head=(pNode)malloc(sizeof(struct node));
head->next=NULL;
head->num=a;
}
else{
pNode current=head;
while(current->next!=NULL)
current=current->next;
pNode temp=(pNode)malloc(sizeof(struct node));
temp->next=NULL;
temp->num=a;
current->next=temp;
}
return head;
}
最后就是遍历各点,完成入队出队的核心部分
以一个结构数组来储存各点的信息:
struct dis{
int key;
int dis;
};
struct dis dist[9];
for(i=0;i<9;i++)
dist[i].dis=dist[i].key=0;
先初始化第一个点的数据:
dist[0].key=1; //点是否被访问
dist[0].dis=0;//该点到原点距离
int x =0;//用变量x来储存当前遍历的点到原点距离
遍历各点
do{
for(i=0;i<9;i++)
{
if(map[head->num][i]==1&&dist[i].key==0) //访问一个新的点 ,即与head->num相连,且尚未被访问的点。
{
dist[i].key=1;
dist[i].dis=x;
head=add(head,i);
}
}
showLink(head);
head=out(head); //之前遍历的点出队,队列头为下一个
if(head!=NULL)
x=dist[head->num].dis+1; //即下一个点到原点的距离为与他相连的点的+1
}while(head!=NULL);
完整代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int map[9][9]={0};
void show();
struct node;
typedef struct node* pNode;
pNode add(pNode,int);
pNode out(pNode);
struct node{
int num;
pNode next;
};
struct dis{
int key;
int dis;
};
void showLink(pNode);
int main()
{
int i,j,k,a;
for(i=0;i<9;i++)
{
printf("输入与第%d个点相连的点: ",i+1);
while(scanf("%d",&a)!=0)
{
map[i][a-1]=1;
}
getchar();
}
show();
struct dis dist[9];
for(i=0;i<9;i++)
{
dist[i].dis=dist[i].key=0;
}
int x=1;
pNode head=NULL;
head=add(head,0);
dist[0].key=1;
dist[0].dis=0;
//printf("%d",head->num);
do{
for(i=0;i<9;i++)
{
if(map[head->num][i]==1&&dist[i].key==0) //访问一个新的点
{
dist[i].key=1;
dist[i].dis=x;
head=add(head,i);
}
}
head=out(head);
if(head!=NULL)
x=dist[head->num].dis+1;
}while(head!=NULL);
for(i=1;i<9;i++)
{
printf("点:%d 距离:%d \n",i+1,dist[i].dis);
}
}
void show()
{
int i,j;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
printf("%d ",map[i][j]);
}
puts("");
}
}
pNode out(pNode head)
{
if(head->next==NULL)
{
free(head);
return NULL;
}
else{
pNode current=head->next;
free(head);
return current;
}
}
pNode add(pNode head,int a)
{
if(head==NULL)
{
head=(pNode)malloc(sizeof(struct node));
head->next=NULL;
head->num=a;
}
else{
pNode current=head;
while(current->next!=NULL)
current=current->next;
pNode temp=(pNode)malloc(sizeof(struct node));
temp->next=NULL;
temp->num=a;
current->next=temp;
}
return head;
}
测试数据:
2 5 3 4 +
1 5 +
1 6 7 +
1 7 8 +
1 2 +
3 7 +
3 4 6 9 +
4 +
7 +
所生成的邻接矩阵
0 1 1 1 1 0 0 0 0
1 0 0 0 1 0 0 0 0
1 0 0 0 0 1 1 0 0
1 0 0 0 0 0 1 1 0
1 1 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0 0
0 0 1 1 0 1 0 0 1
0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0 0
最终输出结果:
点:2 距离:1
点:3 距离:1
点:4 距离:1
点:5 距离:1
点:6 距离:2
点:7 距离:2
点:8 距离:2
点:9 距离:3
原始的图的图片好像被我弄不见了,描述可能没有那么直观。
更直观的可以看dijkstra算法,虽然算法不一样,但这两个很相似,大体思路一样
代码默认是9个点的图,如要测试其他数据,请更改。