求大神帮忙,这是一个关于最短路径的问题,创建一个表后,无法存下来,第二次打开先前存的数据都没有,经常跳出为什么?
#include<stdio.h>//标准输入输出函数#include <stdlib.h>//标准库头文件
#include<string.h>//编译预处理指令
#define OVERFLOW 0//OVERFLOW 溢出
#define MAXSIZE 15
#define MAXINT 999//最大整数值
#define FALSE 0//错误
#define TRUE 1//正确
typedef struct _path//【path:路径】
{
int adjpark;//邻接点域
int distance;//距离
struct _path *nextpath;//下一个路径
}PathNode,*PList[MAXSIZE];
typedef struct _park//【park:车位】
{
char name[10];//车位名
struct _path *firstpath;//第一个路径
}AdjList[15],parkNode;
typedef struct
{
int parks;//车位数
int paths;//路径数
AdjList list;
}MGraph;
PList head;//列表头
typedef int PathMatrix;//PathMatrix 路径矩阵
typedef int ShortPathTable;//ShortPathTable短路径表
PathMatrix P[MAXSIZE][MAXSIZE];//矩阵p[][]
ShortPathTable D[MAXSIZE];//表d[]
int CreatAdjList(MGraph *G)//创造车位图
{
PathNode *p,*p1,*pre;
int i=0;
printf("请输入车位路径数目\n");
scanf("%d",&G->paths);//存入路径数
printf("请输入车位数目\n");
scanf("%d",&G->parks);//存入车位数
for(i=0; i<G->parks; i++)//在i小于车位之前
{
printf("请输入第%d个车位名称\n",i+1);
getchar();//获取字符getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中
//直到用户按回车为止(回车字符也放在缓冲区中).
scanf("%s",G->list[i].name);//%s,字符串,
G->list[i].firstpath=(PathNode *)malloc(sizeof(PathNode));//给指针变量进行相应的地址分配
p=G->list[i].firstpath;
printf("请输入车位第一条路径的邻接车位的位置(-1表示结束)\n");
scanf("%d",&p->adjpark);
printf("请输入车位第一条路径的距离\n");
scanf("%d",&p->distance);
if(p->adjpark==-1)
{
free(p);//释放malloc(或calloc、realloc)函数给指针变量分配的内存空间的函数
//使用后该指针变量一定要重新指向NULL,防止野指针出现,有效 规避误操作。
p=NULL;
G->list[i].firstpath = NULL;//把弧链表的first置为NULL
}
while(p)
{
p->nextpath=(PathNode *)malloc(sizeof(PathNode));
pre=p;
p=p->nextpath;//指针交换指向下一个数据结构体
printf("请输入车位下一条路径的邻接车位(-1表示结束)\n");
scanf("%d",&p->adjpark);
if(p->adjpark==-1)
{
free(p);
p=NULL;
pre->nextpath = NULL;//置pre为弧链表结束的节点
break;
}
printf("请输入车位下一条路径的距离\n");
scanf("%d",&p->distance);
}
}
return 0;
}
int ReadAdjList(MGraph *G)//读取车位图
{
FILE *fp;
int r,i;
PathNode *p,*p1,*pre;
if(( fp=fopen("MGraph.txt","r"))==NULL)
{
printf("文件打开失败");
exit(0);
}
r=fscanf(fp,"%d %d ",&G->paths,&G->parks);
if(r==2)
{
for(i=0; i<G->parks; i++)
{
fscanf(fp,"%s",G->list[i].name);
G->list[i].firstpath=(PathNode *)malloc(sizeof(PathNode));
p=G->list[i].firstpath;
fscanf(fp,"%d",&p->adjpark);
if(p->adjpark==-1)
{
free(p);
p=NULL;
G->list[i].firstpath = NULL;//把弧链表的first置为NULL
break;
}
else
fscanf(fp,"%d",&p->distance);
while(1)
{
p->nextpath=(PathNode *)malloc(sizeof(PathNode));
pre = p;
p=p->nextpath;
fscanf(fp,"%d",&p->adjpark);
if(p->adjpark==-1)
{
free(p);
p=NULL;
pre->nextpath = NULL;//置pre为弧链表结束的节点
break;
}
else
fscanf(fp,"%d",&p->distance);
}
}
}
fclose(fp);
return 0;
}
int WriteAdjList(MGraph *G)//读取车位图
{
FILE *fp;
int r,i;
PathNode *p,*p1;
if(( fp=fopen("MGraph.txt","w"))==NULL)
{
printf("文件打开失败");
exit(0);
}
fprintf(fp,"%d %d ",G->paths,G->parks);
//fprintf()会根据参数format 字符串来转换并格式化数据, 然后将结果输出到参数stream 指定的文件中, 直到出现字符串结束('\0')为止。
for(i=0; i<G->parks; i++)
{
fprintf(fp,"%s ",G->list[i].name);
p=G->list[i].firstpath;
while(p)
{
fprintf(fp,"%d %d ",p->adjpark,p->distance);
p=p->nextpath;
}
fprintf(fp,"-1 ");
}
fclose(fp);
//fclose是一个函数名,功能是关闭一个流。注意:使用fclose()函数就可以把缓冲区内最后剩余的数据输出到内核缓冲区,并释放文件指针和有关的缓冲区。
return 0;
}
void ADD_PATH(MGraph *G,int ori,int add,PathNode p)//添加路径
{
PathNode *pr;
pr=(PathNode *)malloc(sizeof(PathNode));
pr->adjpark=add;
pr->distance=p.distance;
pr->nextpath=G->list[ori].firstpath;
G->list[ori].firstpath=pr;
}
void ADD_park(MGraph *G)//添加车位
{
int i=0;
PathNode *p,*pre;
if(G->parks>=MAXSIZE) return ;
while(strcmp(G->list[i].name,"0")!=0)
i++;
G->parks++;
printf("请输入%d车位的名称\n",i+1);
getchar();
scanf("%s",G->list[i].name);
G->list[i].firstpath=(PathNode *)malloc(sizeof(PathNode));
p=G->list[i].firstpath;
printf("请输入车位第一条路径的邻接车位的位置(-1表示结束)\n");
scanf("%d",&p->adjpark);
printf("请输入车位第一条路径的距离\n");
scanf("%d",&p->distance);
if(p->adjpark==-1)
{
free(p);
p=NULL;
G->list[i].firstpath = NULL;//把弧链表的first置为NULL
}
else
{
ADD_PATH(G,p->adjpark,i,*p);
}
while(p)
{
p->nextpath=(PathNode *)malloc(sizeof(PathNode));
pre = p;
p=p->nextpath;
printf("请输入车位下一条路径的邻接车位(-1表示结束)\n");
scanf("%d",&p->adjpark);
printf("请输入车位下一条路径的距离\n");
scanf("%d",&p->distance);
if(p->adjpark==-1)
{
free(p);
p=NULL;
pre->nextpath = NULL;//置pre为弧链表结束的节点
}
else
{
ADD_PATH(G,p->adjpark,i,*p);
}
}
}
void UPDATE_park(MGraph *G,int park,char *name)
{
strcpy(G->list[park].name,name);
}
int Findpark(MGraph *G,char name[])//返回车位的序号
{
int i;
for(i=0; i<G->parks; i++)
{
if(strcmp(name,G->list[i].name)==0)
return i;
}
return -1;
}
void UPDATE_PATH(MGraph *G,int left,int right)
{
PathNode *p;
int dis;
printf("请输入修改后的路径距离\n");
scanf("%d",&dis);
p=G->list[left].firstpath;
while(1)
{
if(right==p->adjpark)
{
p->distance=dis;
break;
}
p=p->nextpath;
}
p=G->list[right].firstpath;
while(1)
{
if(left==p->adjpark)
{
p->distance=dis;
break;
}
p=p->nextpath;
}
return ;
}
void DELETE_PATH(MGraph *G,int left,int right)
{
PathNode *p,*pre;
int dis;
p=G->list[left].firstpath;
pre=p;
while(p)
{
if(right==p->adjpark)
{
break;
}
p=p->nextpath;
}
while(1)
{
if(p==G->list[left].firstpath)
{
G->list[left].firstpath=p->nextpath;
free(p);
break;
}
if(pre->nextpath==p)
{
pre->nextpath=p->nextpath;
free(p);
break;
}
}
p=G->list[right].firstpath;
pre=p;
while(p)
{
if(left==p->adjpark)
{
break;
}
p=p->nextpath;
}
while(1)
{
if(p==G->list[right].firstpath)
{
G->list[right].firstpath=p->nextpath;
free(p);
break;
}
if(pre->nextpath==p)
{
pre->nextpath=p->nextpath;
free(p);
break;
}
}
return ;
}
void DELETE_park(MGraph *G,int park)
{
int i;
while(G->list[park].firstpath)
{
DELETE_PATH(G,park,G->list[park].firstpath->adjpark);
}
G->parks--;
for(i=park+1; i<=G->parks; i++)
G->list[i-1]=G->list[i];
}
void menu(int i)
{
switch(i)
{
case 0:
printf("*******************************\n");
printf("******管理员模板请输入 1*******\n");
printf("******客户模板请输入 2*******\n");
printf("******退出系统 3*******\n");
printf("*******************************\n");
break;
case 1:
printf("*****************************\n");
printf("*请输入您要进行的操作********\n");
printf("***初始化车位图 1**********\n");
printf("***更新车位图信息 2**********\n");
printf("***删除车位图信息 3**********\n");
printf("***添加车位图信息 4**********\n");
printf("***创建车位图 5**********\n");
printf("***退出 6**********\n");
printf("*****************************\n");
break;
case 2:
printf("*******************************************\n");
printf("***请输入您要进行的操作: ***\n");
printf("***咨询某车位到其他所有车位的最短路径 1***\n");
printf("***咨询所有车位间的最短路径 2***\n");
printf("***咨询两车位间的最短路径 3***\n");
printf("***浏览地图的邻接表表示 4***\n");
printf("***退出 5***\n");
printf("*******************************************\n");
break;
}
}
void initalize_MGraph(MGraph *G)
{
int i;
for(i=0; i<MAXSIZE; i++)//#define MAXSIZE 15
{
strcpy(G->list[i].name,"0");
G->list[i].firstpath=NULL;
}
}
void MODE_ADMIN(MGraph *G)
{
int i=0,j;
char name[20],name1[20];
PathNode *p;
while(1)
{
menu(1);
scanf("%d",&i);
switch(i)
{
case 1:
initalize_MGraph(G);
printf("初始化完成!\n");
break;
case 2:
printf("1:修改车位名\n2:修改路径距离\n3:返回上一层\n");
scanf("%d",&j);
if(j==1)
{
printf("请输入要修改的车位名称\n");
gets(name);
printf("请输入要修改后的车位名称\n");
gets(name1);
UPDATE_park(G, Findpark(G,name),name1);
printf("修改完成!\n");
}
else if(j==2)
{
printf("请输入要修改的两个中第一个车位的名称\n");
gets(name);
printf("请输入要修改的两个中第二个车位的名称\n");
gets(name1);
UPDATE_PATH(G,Findpark(G,name),Findpark(G,name1));
printf("修改完成!\n");
}
else
break;
break;
case 3:
printf("1:删除车位\n2:删除路径\n3:返回上一层\n");
scanf("%d",&j);
if(j==1)
{
printf("请输入要删除的车位名称\n");
gets(name);
DELETE_park(G,Findpark(G,name));
printf("删除完成!\n");
}
else if(j==2)
{
printf("请输入要删除的路径中第一个车位的名称\n");
gets(name);
printf("请输入要修改的两个中第二个车位的名称\n");
gets(name1);
DELETE_PATH(G,Findpark(G,name),Findpark(G,name1));
printf("删除完成!\n");
}
else
break;
break;
case 4:
printf("1:添加车位\n2:添加路径\n3:返回上一层\n");
scanf("%d",&j);
if(j==1)
{
ADD_park(G);
printf("添加完成!\n");
}
else if(j==2)
{
p=(PathNode *)malloc(sizeof(PathNode));
printf("请输入要添加的路径中第一个车位的名称\n");
gets(name);
printf("请输入要添加的两个中第二个车位的名称\n");
gets(name1);
printf("请输入要添加的路径的距离\n");
scanf("%d",p->adjpark);
ADD_PATH(G,Findpark(G,name),Findpark(G,name1),*p);
ADD_PATH(G,Findpark(G,name1),Findpark(G,name),*p);
printf("添加完成!\n");
}
else
break;
break;
case 5:
CreatAdjList(G);
printf("创建完成!\n");
break;
case 6:
menu(0);
default :
return ;
}
WriteAdjList(G);
}
}
int dis(MGraph *G,int left,int right)
{
PathNode *p;
p=G->list[left].firstpath;
while(p)
{
if(right==p->adjpark)
{
return p->distance;
}
p=p->nextpath;
}
return MAXINT;
}
void ShortestPath(MGraph *G,int v0)
{
int i,w,v,min,l=0;
int final[MAXSIZE];//Dijkstra tool
for(v=0; v<G->parks; v++)
{
final[v]=FALSE;
D[v]=dis(G,v0,v);
for(w=0; w<G->parks; w++)
P[v][w]=FALSE;
if(D[v]<MAXINT)
{
P[v][v0]=1;
P[v][w]=1;
}
}
D[v0]=0;
final[v0]=TRUE;
for(i=1; i<G->parks; i++)
{
min=MAXINT;
for(w=0; w<G->parks; w++)
{
if(!final[w])
{
if(D[w]<min)
{
v=w;
min=D[w];
}
}
}
final[v]=TRUE;
for(w=0; w<G->parks; w++)
{
if(!final[w]&&(min+dis(G,v,w)<D[w]))
{
D[w]=min+dis(G,v,w);
strcpy((char*)P[w],(char *)P[v]);
P[w][v]=TRUE;
}
}
}
}
void FindPath(MGraph *G,int v)
{
int i=0;
for(i=0; i<MAXSIZE; i++)
if(P[v][i]==1)
if(dis(G,v,i)<MAXINT)
printf("%s---->",G->list[i].name);
}
void Print(MGraph *G,int v0)
{
int i;
PathNode *p,*pre;
for(i=0; i<G->parks; i++)
{
if(i!=v0)
{
printf("%s到%s的最短距离为%d,路径如下:\n",G->list[v0].name,G->list[i].name,D[i]);
printf("%s---->",G->list[v0].name);
P[i][v0]=0;
P[i][i]=0;
FindPath(G,i);
printf("%s\n",G->list[i].name);
}
}
}
void Print2(MGraph *G,int v1,int v2)
{
printf("%s到%s的最短距离为%d,路径如下:\n",G->list[v1].name,G->list[v2].name,D[v2]);
printf("%s---->",G->list[v1].name);
P[v2][v1]=0;
P[v2][v2]=0;
FindPath(G,v2);
printf("%s\n",G->list[v2].name);
}
void Print3(MGraph *G)
{
int i;PathNode *p;
for(i=0; i<G->parks; i++)
{
p=G->list[i].firstpath->nextpath;
printf("|%-2d%-12s-->%-12s~%-3d|",
i+1,
G->list[i].name,
G->list[G->list[i].firstpath->adjpark].name,
G->list[i].firstpath->distance);
while(p)
{
printf("-->%-12s~%-3d|",
G->list[p->adjpark].name,
p->distance);
p=p->nextpath;
}
printf("<<");
putchar(10);
}
}
void MODE_CLIENT(MGraph *G)
{
int i,j;
int v0,v1,v2;
char name1[20],name2[20],name[20];
while(1)
{
menu(2);
scanf("%d",&i);
switch(i)
{
case 1:
printf("请输入车位的名称:\n");
scanf("%d",name);
v0=Findpark(G,name);
if(v0==-1)
{
printf("输入有误或者没有该车位!\n");
break;
}
ShortestPath(G,v0);
Print(G,v0);
break;
case 3:
printf("请输入第一个车位的名称:\n");
scanf("%s",name1);
v1=Findpark(G,name1);
printf("请输入第二个车位的名称:\n");
scanf("%s",name2);
v2=Findpark(G,name2);
if(v1==-1||v2==-1)
{
printf("输入有误或者没有该车位!\n");
break;
}
ShortestPath(G,v1);
Print2(G,v1,v2);
break;
case 2:
for(j=0; j<G->parks; j++)
{
ShortestPath(G,j);
Print(G,j);
}
break;
case 4:
Print3(G);
getchar();
getchar();
break;
default:
return ;
}
}
}
int main()
{
MGraph G;
int password;
initalize_MGraph(&G);
menu(0);
scanf("%d",&password);
if(password==1)
{
MODE_ADMIN(&G);
}
if(password==2)
{
MODE_CLIENT(&G);
}
return 0;
}
[此贴子已经被作者于2017-12-19 14:56编辑过]