图的相关设计

用文件来储存图的信息,实现迪杰斯特拉算法和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;
  }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值