最近在Ubuntu下使用wine,那字体一直搞不定,也就没有更新日志。下面的迪杰斯特拉算法是这次数据结构课的作业,顺便把它放上来。这次的结构体定义相当不好,由于思路比较简单,流程图都没整理就开始写。后来发现结构体定义不要又不想改。下次写题目之前一定要整理下流程图。我们的教材是严蔚敏、吴伟民编著的清华大学出版社出版《数据结构(C语言版)》。思路基本上是按照课本里头的。
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include <stdlib.h>
#define MAX 3000//设无穷为3000
typedef struct {
int flag;//判断节点是否在最短路劲集合中
int *weight;
int *road;
}Node;
void DIJ (Node *ve,int sourse,int n);
int main() {
int i,j,n,sourse;
Node *ve;
printf ("Input the number of the NODE:");
scanf ("%d",&n);//读节点数
ve = (Node *) malloc (n*sizeof(Node));//分配空间
if (!ve) exit (0);
printf ("Input the number of the ROAD(The road to itself must not small than 3000,/n/
and if there is none plesae put a number larger than or equal to 3000):/n");
for (i = 0; i<n; i++) {
ve[i].flag = 0;//置0
ve[i].weight = (int *) malloc ( n*sizeof(int) );
ve[i].road = (int *) malloc ( (n+1)*sizeof(int) );//n+1确保不会溢出
if (!ve[i].weight || !ve[i].road) exit (0);
memset (ve[i].road, 0, (n+1)*sizeof(int));//以0作为路径结束标记
for (j = 0; j < n; j++)
scanf ("%d",&ve[i].weight[j]);//读路径值
}
printf ("Input the Sourse:");
scanf ("%d",&sourse);//读起点值
sourse--;
ve[sourse].flag = 1;//起点在最短路径集合中
DIJ(ve,sourse,n);//调用函数
for (i = 0; i<n; i++) {
if (i == sourse ) continue;//自己不用输出
printf ("V%d to V%d/t",sourse+1,i+1);
j = 0;
if (ve[sourse].weight[i] < MAX) { //判断是否有路径
printf ("%d/t",ve[sourse].weight[i]);
do {
printf("V%d ",ve[i].road[j++]);
} while (ve[i].road[j] !=0);
printf ("/n");
} else printf ("NONE/n");
}//输出路径
for (i = 0; i<n; i++) {
free(ve[i].weight);
free(ve[i].road);
}
free(ve);//释放空间
return 0;
}
void DIJ (Node *ve,int sourse,int n) {
int i,j,small;
for (i = 0; i<n; i++) if (ve[sourse].weight[i] < MAX) {
ve[i].road[0] = sourse+1;
ve[i].road[1] = i+1;
}//确定路径
while (1){
for (j=0; j < n && !(!ve[j].flag && (ve[sourse].weight[j] < MAX)); j++);
if (j==n) break;//结束
small = j;
for (i = j+1; i < n; i++)
if ( !ve[i].flag && ve[sourse].weight[i]<MAX) {
if (ve[sourse].weight[i] < ve[sourse].weight[small])
small = i;
}//找ve[sourse].weight里头最小的且不在集合中
ve[small].flag = 1;//把其纳入集合中
for (i = 0; i<n; i++)
if ( !ve[i].flag && ve[small].weight[i] < MAX &&/
ve[small].weight[i]+ve[sourse].weight[small]<ve[sourse].weight[i]) {
ve[sourse].weight[i] = ve[small].weight[i]+ve[sourse].weight[small];
//查看是否有更短路径
for (j = 0; (ve[i].road[j] = ve[small].road[j]) != 0; j++);//重新确定路径
ve[i].road[j] = i+1;
ve[i].road[j+1] = 0;//置结尾表示
}
}
}