用来求单源最短路径
ss和u两个数组,ss存放已计算完的顶点,u存放未计算完的顶点
dis字段标识到此点的距离
步骤
1、初始化,第一个点dis=0,后面的点dis=1000
2、循环n次,n为顶点数
2.1 从u中取出一个dis最小的顶点,放入ss,从u中删除这个顶点
2.2 设取出的顶点为v,遍历v的边,用v的 (dis+边权) 与 (边指向的点的dis) 做比较,保留较小值
2.3 回到2
数据结构
typedef struct Side//边
{
int toVertex;//边指向的点
int data;
struct side *next;
}Side,*sLink;
typedef struct Vertex//顶点
{
int data;
int dis;//距离
sLink first;//第一个边
}Vertex,AdjList[20];
typedef struct Graph//图
{
AdjList adj;//顶点数组,注意不是指针,用.不用->
int n,v;//顶点数,边数
}Graph,*gLink;
创建
void createGraph(gLink g)
{
int n,v,data;
printf("请输入顶点数与边数");
scanf("%d %d",&n,&v);
g->n = n;
g->v = v;
int i;
for(i=0;i<n;i++)
{
printf("请输入顶点%d权值",i);
scanf("%d",&data);
g->adj[i].data = data;
g->adj[i].dis = 1000;
g->adj[i].first = NULL;
}
printf("请输入边信息");
int v1,v2,da;
for(i=0;i<v;i++)
{
scanf("%d %d %d",&v1,&v2,&da);
sLink s = (sLink)malloc(sizeof(Side));
s->toVertex = v2;
s->next = g->adj[v1].first;
g->adj[v1].first = s;
s->data = da;
}
}
算法
snum存放ss的长度,unum存放u的长度
这里ss其实没有什么用,可以省略
void dijkstra(gLink g)
{
//初始化所有路径
g->adj[0].dis = 0;
sLink s = g->adj[0].first;
while(s)
{
int v = s->toVertex;
g->adj[v].dis = s->data;
s=s->next;
}
int i,j;
int ss[15],u[15],snum=0,unum=g->n;//s存完事的边,u存未完事的边
//执行算法
g->adj[0].dis = 0;
for(i=0;i<unum;i++)
{
u[i] = i;
}
while(snum<g->n)
{
//找最近的点加入s,并从u删除
int min=1000;
int index;
for(i=0;i<unum;i++)
{
int v = u[i];
if(g->adj[v].dis<min)
{
min = g->adj[v].dis;
index = i;
}
}
int v = u[index];
ss[snum++] = v;//加入ss
unum--;
for(j=index;j<unum;j++)//从u中删除
{
u[j]=u[j+1];
}
//重新附权值
sLink s = g->adj[v].first;
while(s)
{
if(g->adj[v].dis+s->data<g->adj[s->toVertex].dis)
{
g->adj[s->toVertex].dis = g->adj[v].dis+s->data;
}
s = s->next;
}
}
}
主函数
int main()
{
gLink g = (gLink)malloc(sizeof(Graph));
createGraph(g);
dijkstra(g);
int i;
for(i=0;i<g->n;i++)
{
printf("%-5d",g->adj[i].dis);
}
return 0;
}