用文件来储存图的信息,实现迪杰斯特拉算法和Prim算法,但是文件的操作还是不是很流畅,在del函数中文件无法删除。。。。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXVEX 30
#define INFINITY 32768
typedef struct
{
int no;
char name[20];
} Vextype;
typedef struct
{
int arcs[MAXVEX][MAXVEX];
int times[MAXVEX][MAXVEX]; //时间
int cost[MAXVEX][MAXVEX]; //花费
Vextype vex[MAXVEX];
int vexnum;
int arcnum;
}AdjMatrix;
int citynumber = 0,cutnumber = 0;
int Locate(AdjMatrix *G , char name[])
{
int i;
for(i = 1 ; i <=G->vexnum;i++)
if(!strcmp(name,G->vex[i].name))
return i;
return -1;
}
int Init(AdjMatrix *G)
{
char cityname[20],city1[20],city2[20];
int citynumber = 0,cutnumber = 0;
int weight,cost,times;
int i,j,k;
char ch;
FILE *fp;
if((fp=fopen("AdjNumber.txt","r"))==NULL) { //从新打开
printf("The file %s can not be opened.\n","AdjNumber.txt");
return 0;
}
fscanf(fp,"%d %d",&G->vexnum,&G->arcnum);
fclose(fp);
if((fp=fopen("AdjCity.txt","r"))==NULL) {
printf("The file %s can not be opened.\n","AdjCity.txt");
return 0;
}
for(int i = 1 ; i <=G->vexnum ; i++)
{
fscanf(fp,"%s",cityname);
strcpy(G->vex[i].name,cityname); //xitsumen
G->vex[i].no = i;
}
fclose(fp);
//完全存入城市节点信息↑
if((fp=fopen("AdjMatrix.txt","r"))==NULL) {
printf("The file %s can not be opened.\n","AdjMatrix.txt");
return 0;
}
for(int i = 1 ; i <= G->arcnum ; i++)
{
fscanf(fp,"%s %s %d %d %d",city1,city2,&weight,&cost,×);
j = Locate(G,city1);
k = Locate(G,city2);
G->arcs[k][j] = weight;
G->arcs[j][k] = weight;
G->cost[k][j] = cost;
G->cost[j][k] = cost;
G->times[k][j] = times;
G->times[j][k] = times;
}
}
int Display(AdjMatrix *G)
{
int i,j;
FILE *fp;
if((fp=fopen("AdjNumber.txt","r"))==NULL) {
printf("The file %s can not be opened.\n","AdjNumber.txt");
return 0;
}
fscanf(fp,"%d %d",&G->vexnum,&G->arcnum);
fclose(fp);
printf("%d %d",G->vexnum,G->arcnum);
printf("\n城市交通情况为::\n");
for(i = 1 ; i <= G->vexnum ; i++)
{
for(j = 1 ; j <=i;j++)
{
if(G->arcs[i][j]!=INFINITY)
printf("%s<--> %s:%3dkm, spend %d times ,cost %d RMB\n",G->vex[i].name,G->vex[j].name,G->arcs[i][j],G->times[i][j],G->cost[i][j]);
}
}
}
void Search(AdjMatrix *G)
{
char city[20];
int no,i,j;
printf("请输入查找城市:");
scanf("%s",city);
no = Locate(G,city);
printf("该城市交通状况为 :\n");
for(i = 1 ; i <=G->vexnum ; i++)
if(i == no)
for(j = 1 ; j <=G->vexnum ; j++)
if(G->arcs[i][j]!= INFINITY)
printf("%s---%s:%dkm, spend %d times ,cost %d RMB \n",G->vex[no].name,G->vex[j].name,G->arcs[i][j],G->times[i][j],G->cost[i][j]);
}
int AddCity(AdjMatrix *G) //只添加一个城市
{
char city[20];
FILE *fp;
if((fp=fopen("AdjCity.txt","a+"))==NULL) {
printf("The file %s can not be opened.\n","AdjCity.txt");
return 0;
}
fscanf(stdin,"%s",city);
fprintf(fp,"%s",city);
fputc('\n',fp);
fclose(fp);
//接下来对AdjNumber进行操作 r+ 打开可读可写的文件,该文件必须存在(这里的写文件是指将之前的文件覆盖
if((fp=fopen("AdjNumber.txt","r"))==NULL) { //读取两个数字(该+1的一方+1),删除文件,创建文件,写入数字
printf("The file %s can not be opened.\n","AdjNumber.txt");
return 0;
}
fscanf(fp,"%d %d",&G->vexnum,&G->arcnum);
G->vexnum++;
fclose(fp);
if((fp=fopen("AdjNumber.txt","r+"))==NULL) {
printf("The file %s can not be opened.\n","AdjNumber.txt");
return 0;
}
fprintf(fp,"%d %d",G->vexnum,G->arcnum);
fclose(fp);
strcpy(G->vex[G->vexnum].name,city);
G->vex[G->vexnum].no = G->vexnum;
Init(G);
}
int Add(AdjMatrix *G) //添加一条路线,包括花费,时间等
{
char city1[20],city2[20];
int weight,cost,times;
FILE *fp;
if((fp=fopen("AdjMatrix.txt","a+"))==NULL) {
printf("The file %s can not be opened.\n","AdjMatrix.txt");
return 0;
}
printf("请输入城市名字,距离,花费,时间:\n") ;
fscanf(stdin,"%s %s %d %d %d",city1,city2,&weight,&cost,×);
fprintf(fp,"%s %s %d %d %d",city1,city2,weight,cost,times); //后三个不用%4d
fputc('\n',fp);
fclose(fp);
if((fp=fopen("AdjNumber.txt","r"))==NULL) { //读取两个数字(该+1的一方+1),删除文件,创建文件,写入数字 ,读取数据
printf("The file %s can not be opened.\n","AdjNumber.txt");
return 0;
}
fscanf(fp,"%d %d",&G->vexnum,&G->arcnum);
G->arcnum++;
fclose(fp);
if((fp=fopen("AdjNumber.txt","r+"))==NULL) { //覆盖数据
printf("The file %s can not be opened.\n","AdjNumber.txt");
return 0;
}
fprintf(fp,"%d %d",G->vexnum,G->arcnum);
fclose(fp);
G->arcs[Locate(G,city1)][Locate(G,city2)] = weight;
G->arcs[Locate(G,city2)][Locate(G,city1)] = weight;
G->times[Locate(G,city1)][Locate(G,city2)] = times;
G->times[Locate(G,city2)][Locate(G,city1)] = times;
G->cost[Locate(G,city1)][Locate(G,city2)] = cost;
G->cost[Locate(G,city2)][Locate(G,city1)] = cost;
Init(G);
}
int Del(AdjMatrix *G)
{
FILE *fin,*ftp,*fp;
char city1[20],city2[20],a[1000],del1[20],del2[20],last1[20],last2[20];
int weight,cost,times;
bool temp = false;
fin=fopen("AdjMatrix.txt","r");//读打开原文件123.txt
ftp=fopen("tmp123.txt","w");//写打开临时文件tmp.txt
scanf("%s %s",del1,del2);
fscanf(fin,"%s %s %d %d %d",city1,city2,&weight,&cost,×);//第一行的操作
if((strcmp(city1,del1)==0 && strcmp(city2,del2)==0) || (strcmp(city2,del1)==0 && strcmp(city1,del2)==0))
{
temp = true;
}
if(!temp)
{
fprintf(ftp,"%s %s %d %d %d",city1,city2,weight,cost,times);
fputc('\n',ftp);
}
else
temp = false;
while(fgets(a,1000,fin))
{
fscanf(fin,"%s %s %d %d %d",city1,city2,&weight,&cost,×);
if((strcmp(city1,del1)==0 && strcmp(city2,del2)==0) || (strcmp(city2,del1)==0 && strcmp(city1,del2)==0))
{
temp = true;
}
if(strcmp(city1,last1)==0 && strcmp(city2,last2)==0)
{
temp = true;
}
if(!temp)
{
strcpy(last1,city1);
strcpy(last2,city2);
fprintf(ftp,"%s %s %d %d %d",city1,city2,weight,cost,times);
fputc('\n',ftp);
}
else
temp = false;
}
// if((fp=fopen("AdjNumber.txt","r"))==NULL) {
// printf("The file %s can not be opened.\n","AdjNumber.txt");
// return 0;
// }
// fscanf(fp,"%d %d",&G->vexnum,&G->arcnum);
// G->arcnum--;
// fclose(fp);
// if((fp=fopen("AdjNumber.txt","r+"))==NULL) { //覆盖数据
// printf("The file %s can not be opened.\n","AdjNumber.txt");
// return 0;
// }
//
// fprintf(fp,"%d %d",G->vexnum,G->arcnum);
// fclose(fp);
fclose(fin);
fclose(ftp);
fp=fopen("AdjMatrix.txt","r");
if(fp==NULL) //检测存在
{
printf("bucunzai");
}
else
{
fclose(fp);
}
if(remove("AdjMatrix.txt")==-1)
printf("remove失败了!!!");//删除原文件
rename("tmp123.txt","AdjMatrix.txt");//将临时文件名改为原文件名
Init(G);
}
void Dijkstra(AdjMatrix *G , int start , int end , int dist[],int path[][MAXVEX])
{
int mindist,i,j,k,t = 1;
for(i = 1 ; i <=G->vexnum ; i++) //初始化
{
dist[i] = G->arcs[start][i];
if(G->arcs[start][i]!=INFINITY)
path[i][1] = start;
}
path[start][0] = 1;
for(i = 2 ; i <=G->vexnum ; i++)
{
mindist = INFINITY;
for(j = 1;j<=G->vexnum;j++)
if(!path[j][0] && dist[j]<mindist)
{
k = j;
mindist = dist[j];
}
// printf("up\n");
if(mindist==INFINITY) break;//原来为return
path[k][0] = 1;
for(j = 1 ; j <G->vexnum;j++)
{
if(!path[j][0] && G->arcs[k][j]<INFINITY && dist[k]+G->arcs[k][j]<dist[j])
{
dist[j] = dist[k]+G->arcs[k][j];
t = 1;
while(path[k][t]!=0)
{
path[j][t] = path[k][t];
t++;
}
path[j][t] = k;
path[j][k+1] = 0;
}
}
}
for(i = 1 ; i <=G->vexnum;i++)
if(i==end) break;
printf("%s-->%s的最短路线为:从%s",G->vex[start].name,G->vex[end].name,G->vex[start].name);
for(j = 2 ; path[i][j]!=0 ; j++)
printf("->%s",G->vex[path[i][j]].name);
printf("->%s,距离为%dkm\n",G->vex[end].name,dist[i]);
}
void Shortcut(AdjMatrix *G)
{
char city1[20],city2[20];
int start,end;
int dist[MAXVEX],path[MAXVEX][MAXVEX] = {0};
scanf("%s %s",city1,city2); //不用&
start = Locate(G,city1);
end = Locate(G,city2);
printf("%d %d",start,end);
Dijkstra(G,start,end,dist,path);
}
void Dijkstra_times(AdjMatrix *G , int start , int end , int dist[],int path[][MAXVEX])
{
int mindist,i,j,k,t = 1;
for(i = 1 ; i <=G->vexnum ; i++) //初始化
{
dist[i] = G->times[start][i];
if(G->times[start][i]!=INFINITY)
path[i][1] = start;
}
path[start][0] = 1;
for(i = 2 ; i <=G->vexnum ; i++)
{
mindist = INFINITY;
for(j = 1;j<=G->vexnum;j++)
if(!path[j][0] && dist[j]<mindist)
{
k = j;
mindist = dist[j];
}
// printf("up\n");
if(mindist==INFINITY) break;//原来为return
path[k][0] = 1;
for(j = 1 ; j <G->vexnum;j++)
{
if(!path[j][0] && G->times[k][j]<INFINITY && dist[k]+G->times[k][j]<dist[j])
{
dist[j] = dist[k]+G->times[k][j];
t = 1;
while(path[k][t]!=0)
{
path[j][t] = path[k][t];
t++;
}
path[j][t] = k;
path[j][k+1] = 0;
}
}
}
for(i = 1 ; i <=G->vexnum;i++)
if(i==end) break;
printf("%s-->%s的最快路线为:从%s",G->vex[start].name,G->vex[end].name,G->vex[start].name);
for(j = 2 ; path[i][j]!=0 ; j++)
printf("->%s",G->vex[path[i][j]].name);
printf("->%s,花费%d Minute\n",G->vex[end].name,dist[i]);
}
void Shortcut_times(AdjMatrix *G)
{
char city1[20],city2[20];
int start,end;
int dist[MAXVEX],path[MAXVEX][MAXVEX] = {0};
scanf("%s %s",city1,city2); //不用&
start = Locate(G,city1);
end = Locate(G,city2);
Dijkstra_times(G,start,end,dist,path);
}
void Dijkstra_cost(AdjMatrix *G , int start , int end , int dist[],int path[][MAXVEX])
{
int mindist,i,j,k,t = 1;
for(i = 1 ; i <=G->vexnum ; i++) //初始化
{
dist[i] = G->cost[start][i];
if(G->cost[start][i]!=INFINITY)
path[i][1] = start;
}
path[start][0] = 1;
for(i = 2 ; i <=G->vexnum ; i++)
{
mindist = INFINITY;
for(j = 1;j<=G->vexnum;j++)
if(!path[j][0] && dist[j]<mindist)
{
k = j;
mindist = dist[j];
}
// printf("up\n");
if(mindist==INFINITY) break;//原来为return
path[k][0] = 1;
for(j = 1 ; j <G->vexnum;j++)
{
if(!path[j][0] && G->times[k][j]<INFINITY && dist[k]+G->cost[k][j]<dist[j])
{
dist[j] = dist[k]+G->cost[k][j];
t = 1;
while(path[k][t]!=0)
{
path[j][t] = path[k][t];
t++;
}
path[j][t] = k;
path[j][k+1] = 0;
}
}
}
for(i = 1 ; i <=G->vexnum;i++)
if(i==end) break;
printf("%s-->%s的最小花费为:从%s",G->vex[start].name,G->vex[end].name,G->vex[start].name);
for(j = 2 ; path[i][j]!=0 ; j++)
printf("->%s",G->vex[path[i][j]].name);
printf("->%s,花费为%dRMB\n",G->vex[end].name,dist[i]);
}
void Shortcut_cost(AdjMatrix *G)
{
char city1[20],city2[20];
int start,end;
int dist[MAXVEX],path[MAXVEX][MAXVEX] = {0};
scanf("%s %s",city1,city2); //不用&
start = Locate(G,city1);
end = Locate(G,city2);
Dijkstra_times(G,start,end,dist,path);
}
void Prim(AdjMatrix *G , int start)
{
struct
{
int adjvex;
int lowcost;
}closedge[MAXVEX];
int i,e,k,m,min;
closedge[start].lowcost = 0;
for(i = 1 ; i <= G->vexnum ; i++)
if(i!= start)
{
closedge[i].adjvex =start;
closedge[i].lowcost = G->arcs[start][i];
}
for(e = 1 ; e <= G->vexnum-1;e++)
{
min = INFINITY;
for(k = 1 ; k <=G->vexnum ; k++)
{
if(closedge[k].lowcost !=0 && closedge[k].lowcost<min)
{
m = k ;
min = closedge[k].lowcost;
}
}
printf("从%s--%s:%dkm\n",G->vex[closedge[m].adjvex].name,G->vex[m].name,closedge[m].lowcost);
closedge[m].lowcost = 0;
for(i = 1;i <=G->vexnum ; i++)
if(i!=m && G->arcs[m][i]<closedge[i].lowcost)
{
closedge[i].lowcost = G->arcs[m][i];
closedge[i].adjvex = m;
}
}
}
void MiniSpanTree(AdjMatrix *G)
{
char city[20];
int start;
printf("请输入起点城市:");
scanf("%s",city);
start = Locate(G,city);
Prim(G,start);
}
void Prim_times(AdjMatrix *G , int start)
{
struct
{
int adjvex;
int lowcost;
}closedge[MAXVEX];
int i,e,k,m,min;
closedge[start].lowcost = 0;
for(i = 1 ; i <= G->vexnum ; i++)
if(i!= start)
{
closedge[i].adjvex =start;
closedge[i].lowcost = G->times[start][i];
}
for(e = 1 ; e <= G->vexnum-1;e++)
{
min = INFINITY;
for(k = 1 ; k <=G->vexnum ; k++)
{
if(closedge[k].lowcost !=0 && closedge[k].lowcost<min)
{
m = k ;
min = closedge[k].lowcost;
}
}
printf("从%s--%s:%d times\n",G->vex[closedge[m].adjvex].name,G->vex[m].name,closedge[m].lowcost);
closedge[m].lowcost = 0;
for(i = 1;i <=G->vexnum ; i++)
if(i!=m && G->times[m][i]<closedge[i].lowcost)
{
closedge[i].lowcost = G->times[m][i];
closedge[i].adjvex = m;
}
}
}
void MiniSpanTree_times(AdjMatrix *G)
{
char city[20];
int start;
printf("请输入起点城市:");
scanf("%s",city);
start = Locate(G,city);
Prim_times(G,start);
}
void Prim_cost(AdjMatrix *G , int start)
{
struct
{
int adjvex;
int lowcost;
}closedge[MAXVEX];
int i,e,k,m,min;
closedge[start].lowcost = 0;
for(i = 1 ; i <= G->vexnum ; i++)
if(i!= start)
{
closedge[i].adjvex =start;
closedge[i].lowcost = G->cost[start][i];
}
for(e = 1 ; e <= G->vexnum-1;e++)
{
min = INFINITY;
for(k = 1 ; k <=G->vexnum ; k++)
{
if(closedge[k].lowcost !=0 && closedge[k].lowcost<min)
{
m = k ;
min = closedge[k].lowcost;
}
}
printf("从%s--%s:%d RMB\n",G->vex[closedge[m].adjvex].name,G->vex[m].name,closedge[m].lowcost);
closedge[m].lowcost = 0;
for(i = 1;i <=G->vexnum ; i++)
if(i!=m && G->cost[m][i]<closedge[i].lowcost)
{
closedge[i].lowcost = G->cost[m][i];
closedge[i].adjvex = m;
}
}
}
void MiniSpanTree_cost(AdjMatrix *G)
{
char city[20];
int start;
printf("请输入起点城市:");
scanf("%s",city);
start = Locate(G,city);
Prim_cost(G,start);
}
main()
{
AdjMatrix G;
int choice;
bool end = true;
int i,j;
for(i = 1 ; i <=MAXVEX;i++)
for(j = 1 ; j <=MAXVEX ; j++)
{
G.arcs[i][j] = INFINITY;
G.cost[i][j] = INFINITY;
G.times[i][j] = INFINITY;
}
Init(&G);
// printf("%d %d",G.arcnum,G.vexnum);
do{
printf("**********************************************************\n");
printf("* Press 1 to display the adjmatrix: \n");
printf("* Press 2 to search thr city : \n");
printf("* Press 3 to add one city : \n");
printf("* Press 4 to add a distance times costs : \n");
printf("* Press 5 to delete a city: \n");
printf("* Press 6 to show the shortcut by distance: \n");
printf("* Press 7 to show the shortcut by times: \n");
printf("* Press 8 to show the shortcut by costs: \n");
printf("* Press 9 to show the minispantree by distance: \n");
printf("* Press 10 to show the minispantree by times: \n");
printf("* Press 11 to show the minispantree by costs: \n");
printf("**********************************************************\n");
scanf("%d",&choice);
switch(choice)
{
case 1:Display(&G);break;
case 2:Search(&G);break;
case 3:AddCity(&G);break;
case 4:Add(&G);break;
case 5:Del(&G);break; //1.2
case 6:Shortcut(&G);break;
case 7:Shortcut_times(&G);break;
case 8:Shortcut_cost(&G);break;
case 9:MiniSpanTree(&G);break;
case 10:MiniSpanTree_times(&G);break;
case 11:MiniSpanTree_cost(&G);break;
case 0:end = false;break;
}
}while(end);
return 1;
}