/*
离散数学里介绍了一下两点间图的最短路径,看着挺好玩得,那么多点,可以自动找到两点间的最短路线?
自己试着编一个程序来实现。还是那句话,只注重理解,忽略代码质量。理解不对,有人看见了说一声。
求a到j间的最小路径
将a看成一个集合S1={a},剩下的看作T1={b,c,d,e,f,g,h,i,j}
找S1到T1最短的路径,将找到的顶点放入S1
S2={a,b} T2={c,d,e,f,g,h,i,j}
再从S2中想T2找最短的路径,将找到的顶点放入S2
S3={a,b,e} T2={c,d,f,g,h,i,j}
..........
Sn={a,b,c,d,e,f,g,h,i,j} Tn={}
*/
#include <stdio.h>
#define M 1000 //不知道无穷怎么写,^_^
//a,b,c,d,e,f,g,h,i,j
//0,1,2,3,4,5,6,7,8,9
//定义图的邻接矩阵
int map[10][10]={
M,1,10,6,3,M,M,M,M,M,
1,M,10,M,M,10,M,M,M,M,
10,10,M,4,M,1,4,1,M,M,
6,M,4,M,2,M,M,3,M,M,
3,M,M,2,M,M,M,6,8,M,
M,10,1,M,M,M,2,M,M,5,
M,M,4,M,M,2,M,5,M,2,
M,M,1,3,6,M,5,M,3,8,
M,M,M,M,8,M,M,3,M,5,
M,M,M,M,M,5,2,8,5,M
};
main()
{
int i;
//记录路径权值
int D[10]={0,1,10,6,3,M,M,M,M,M};
//查表
char b[10]={'a','b','c','d','e','f','g','h','i','j'};
struct source
{
int data;
int fore;
int next;
};//双指针静态链表结构
struct direct
{
int data[10];
int tail;
};
//集合S1转向集合s2,1表示存在,0表示不存在
struct source s1[10];
for(i=0;i<10;i++)
{
s1[i].data=i;
s1[i].fore=i-1;
s1[i].next=i+1;
}
s1[9].next=0;//用0作为静态链表的结束标志
struct direct s2;
s2.tail=0;
for(i=0;i<10;i++)
s2.data[i]=0;
int data1,data2;
int x,y;
int p;//p指向s1的元素y的下标
while(s1[0].next!=0)
{
int Min[2]={M,1};
x=s2.data[s2.tail];
p=s1[0].next;//p指向要比较的元素
//------------------------------------------------------------
//搜索一遍s1
while(p!=0)
{
y=s1[p].data;
data1=D[y];//a到其他元素的值
data2=D[x]+map[x][y];//最短路径点x到其他元素的值
//判断出最短路径的点
if(data1<data2)
{
D[y]=data1;
if(data1<Min[0])
{
Min[0]=data1;
Min[1]=p;
}
}
else
{
D[y]=data2;
if(data2<Min[0])
{
Min[0]=data2;
Min[1]=p;
}
}
p=s1[p].next;
}
//-----------------------------------------------------
//从s1搜索一遍后,找到了最小的点,移到s2中,删除下标为q的点
s2.tail++;
s2.data[s2.tail]=s1[Min[1]].data;
s1[s1[Min[1]].fore].next=s1[Min[1]].next;
s1[s1[Min[1]].next].fore=s1[Min[1]].fore;
}
x=s2.tail;
y=s2.tail;
printf("%c",b[s2.data[x]]);
while(y!=0)
{
if(map[s2.data[x]][s2.data[y]]==M)
x--;
else
{
printf("<-%c",b[s2.data[x]]);
y=x;
x--;
}
}
printf("/n");
}