您的位置:首页 > 理论基础 > 数据结构算法

数据结构课设之 景点管理系统

2015-03-04 13:50 120 查看
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define MVNum 100//最大顶点数
#define MAXEDGE 10000
#define datatype int
#define Maxint 32767//最大
#define MAX 100
#define MAX_VERTEX_NUM 20
int D1[MVNum],p1[MVNum];
int D[MVNum][MVNum],p[MVNum][MVNum];
int visited[MAX_VERTEX_NUM];	// 访问标志数组(全局量)
typedef struct
{
int num;
char name[20];
}VertexType;
typedef struct
{
VertexType begin;
VertexType end;
int weight;
}edge;
typedef struct
{
int adj;
int weight;
}AdjMatrix[MAX][MAX];
typedef struct
{
AdjMatrix arc;
int vexnum, arcnum;
}MGraph;
void zuijiapath(MGraph *G);
void luru()
{
int w;
FILE *fp;
int k;
int vexnum,arcnum,num1,num2;
char name[20];
if((fp=fopen("d:\\goyuan.txt","w"))==NULL)
{
printf("cannot open in file");
exit(0);
}
printf("请输入图的顶点数和边数:(空格)\n");
scanf("%d",&vexnum);
fprintf(fp,"%d\n",vexnum);
scanf("%d",&arcnum);
fprintf(fp,"%d\n",arcnum);
printf("\n请输入有边的2个顶点信息:\n");
for(k = 0;k < arcnum; ++k)	// 构造表结点链表
{
printf("请输入景点的编号,名称\n");
scanf("%d",&num1);
fprintf(fp,"%d\n",num1);
scanf("%s",name);
fprintf(fp,"%s\n",name);
printf("请输入景点的编号,名称\n");
scanf("%d",&num2);
fprintf(fp,"%d\n",num2);
scanf("%s",name);
fprintf(fp,"%s\n",name);
printf("请输入两个景点之间的距离\n");
scanf("%d",&w);
fprintf(fp,"%d\n",w);
}
fclose(fp);

}
void CreatGraph(MGraph *G)//函数申明
{
FILE *fp;
int i,j,n1,m1,n,m,w;
int a[21];
for(i=0;i<21;i++)
a[i]=1;
char name1[20],name2[20];
if((fp=fopen("d:\\goyuan.txt","r"))==NULL)
{
printf("cannot open in file");
exit(0);
}
fscanf(fp,"%d",&n);
G->vexnum=n;
fscanf(fp,"%d",&m);
G->arcnum=m;

for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
G->arc[i][j].adj=G->arc[j][i].adj=0;
G->arc[i][j].weight=G->arc[j][i].weight=Maxint;
}
}
printf("景点信息如下\n");
for( i=1;i<=m;i++)
{
fscanf(fp,"%d",&n1);
fscanf(fp,"%s",&name1);
fscanf(fp,"%d",&m1);
fscanf(fp,"%s",&name2);
fscanf(fp,"%d",&w);
G->arc[n1][m1].adj=G->arc[m1][n1].adj = 1;
G->arc[n1][m1].weight=w;
G->arc[m1][n1].weight=G->arc[n1][m1].weight;
if(a[n1]==1)
{
printf("%d.%s\n",n1,name1);
a[n1]=0;
}
if(a[m1]==1)
{
printf("%d.%s\n",m1,name2);
a[m1]=0;
}
}
printf("邻接矩阵为:\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
printf("%d",G->arc[i][j].adj);
}
printf("\n");
}
fclose(fp);

}
void show()
{
printf("             *****************");
printf("   公园导游图    ");
printf("*****************");
printf("\n\n\n");
printf("             *****************");
printf("  1.录入景点信息 ");
printf("*****************");
printf("\n\n\n");
printf("             *****************");
printf("  2.查询景点信息 ");
printf("*****************");
printf("\n\n\n");
printf("             *****************");
printf("  3.查询景点路径 ");
printf("*****************");
printf("\n\n\n");
printf("             *****************");
printf("  4.查询最佳路径 ");
printf("*****************");
printf("\n\n\n");
printf("             *****************");
printf("  0.退出         ");
printf("*****************");
printf("\n\n\n");
printf("请选择选项\n");
}
void Swapn(edge *edges,int i,int j)//交换权值 以及头和尾
{
int temp;
temp = edges[i].begin.num;
edges[i].begin.num = edges[j].begin.num;
edges[j].begin.num = temp;
temp = edges[i].end.num ;
edges[i].end.num  = edges[j].end.num;
edges[j].end.num = temp;
temp = edges[i].weight;
edges[i].weight = edges[j].weight;
edges[j].weight = temp;
}
void sort(edge edges[],MGraph *G,int m)//对权值进行排序
{
int i, j;
for(i=1;i<m;i++)
{
for(j=i+1;j<=m;j++)
{
if(edges[i].weight>edges[j].weight)
{
Swapn(edges,i,j);
}
}
}
printf("权排序之后的为:\n");
for(i=1;i< m;i++)
{
printf("<<%d,%d>> %d\n",edges[i].begin,edges[i].end,edges[i].weight);
}

}
void Floyd(MGraph *G,int n)
{
int i,j,k;
for(i=1;i<=n;i++)//设置路径长度D和路径path初值
for(j=1;j<=n;j++)
{
if(G->arc[i][j].weight!=Maxint)
p[i][j]=j;//j是i的后继
else
p[i][j]=0;
D[i][j]=G->arc[i][j].weight;
}
for(k=1;k<=n;k++)
{   //做k次迭代,每次均试图将顶点k扩充到当前求得的从i到j的最短路径pij上
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(D[i][k]+D[k][j]<D[i][j])
{
D[i][j]=D[i][k]+D[k][j];//修改长度
p[i][j]=p[i][k];
//printf("dij=%d,pij=%d\n",D[i][j],p[i][j]);
}
}
}
}
void shortpath(MGraph *G)
{
FILE *fp;
edge edges[20];
int k;
int v,w;
int i,j,n1,m1,n,m,b;
int a[21];
for(i=0;i<21;i++)
a[i]=1;
char name1[20],name2[20];
if((fp=fopen("d:\\goyuan.txt","r"))==NULL)
{
printf("cannot open in file");
exit(0);
}
fscanf(fp,"%d",&n);
fscanf(fp,"%d",&m);
G->vexnum=n;
G->arcnum=m;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
G->arc[i][j].adj=G->arc[j][i].adj=0;
G->arc[i][j].weight=G->arc[j][i].weight=Maxint;
}
}
for( i=1;i<=m;i++)
{
fscanf(fp,"%d",&n1);
fscanf(fp,"%s",&name1);
fscanf(fp,"%d",&m1);
fscanf(fp,"%s",&name2);
fscanf(fp,"%d",&b);
if(a[n1]==1)
{
edges[n1].begin.num=n1;
strcpy(edges[n1].begin.name,name1);
a[n1]=0;
}
if(a[m1]==1)
{
edges[m1].begin.num=m1;
strcpy(edges[m1].begin.name,name2);
a[m1]=0;
}
G->arc[n1][m1].adj=G->arc[m1][n1].adj = 1;
G->arc[n1][m1].weight=b;
G->arc[m1][n1].weight=G->arc[n1][m1].weight;
}

Floyd(G,n);//调用Floyd算法
printf(" 输入起点和终点: v,w :     ");
scanf("%d%d",&v,&w);
k=p[v][w];//k为起点v的后继顶点
if(k==0)
printf("景点 %d到 %d 无路径!\n",v,w);
else
{
printf("从景点%d到%d的最短路径是:%d",v,w,v);
while(k!=w)
{
printf("->%d",k);//输出后继顶点
k=p[k][w];//继续找下一个后继顶点
}
printf("->%d",w);//输出终点w
printf(" 路径长度: %d\n",D[v][w]);
}
fclose(fp);
}
int  main()
{
int n;
MGraph *G;
G=(MGraph *)malloc(sizeof(MGraph));
if (G == NULL)
{
printf("memory allcation failed,goodbye");
exit(1);
}
show();
scanf("%d",&n);
system("cls");
while(n>0&&n<=4)
{
switch(n)
{
case 1:luru();break;
case 2:CreatGraph(G);break;
case 3:shortpath(G);break;
case 4:zuijiapath(G);break;
}

show();
scanf("%d",&n);
system("cls");

}
}
void zuijiapath(MGraph *G)
{
FILE *fp;
edge edges[20];
int pathsum=0;      //用于存放路径和
int max= 10000;		//代表无穷大
int minpath;  	    //用于存放当前找到的最小路径
int k;
int v,w;
int i,j,n1,m1,n,m,b;
int a[21];
for(i=0;i<21;i++)
a[i]=1;
char name1[20],name2[20];
if((fp=fopen("d:\\goyuan.txt","r"))==NULL)
{
printf("cannot open in file");
exit(0);
}
fscanf(fp,"%d",&n);
fscanf(fp,"%d",&m);
G->vexnum=n;
G->arcnum=m;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
G->arc[i][j].adj=G->arc[j][i].adj=0;
G->arc[i][j].weight=G->arc[j][i].weight=Maxint;
}
}
for( i=0;i<m;i++)
{
fscanf(fp,"%d",&n1);
fscanf(fp,"%s",&name1);
fscanf(fp,"%d",&m1);
fscanf(fp,"%s",&name2);
fscanf(fp,"%d",&b);
if(a[n1]==1)
{
edges[n1].begin.num=n1;
strcpy(edges[n1].begin.name,name1);
a[n1]=0;
}
if(a[m1]==1)
{
edges[m1].begin.num=m1;
strcpy(edges[m1].begin.name,name2);
a[m1]=0;
}
G->arc[n1][m1].adj=G->arc[m1][n1].adj = 1;
G->arc[n1][m1].weight=b;
G->arc[m1][n1].weight=G->arc[n1][m1].weight;
}

int visited[12]={1};//记录顶点的访问情况:visited[d]=0表示d点未访问,visited[d]=1表示d点已被访问
j=0;			//临时存放顶点编号,以便传递给顶点v
//让所有点都记录为未访问。visited[c]=0.
for(int d=1;d<n;d++) //除正门外,所有景点都保证其为被访问:visited[d]=0表示d点未访问,visited[d]=1表示d点已被访问
visited[d]=0;
printf("(0)公园正门");
v=0;//从正门出发
//最佳旅游路线算法开始
for(int flat=0;flat!=G->vexnum;)
{
minpath=10000;
for(int k=1;k<m;k++)	//依次读取与v相邻的所有路径,取未被访问的最小路径
{
if(minpath>G->arc[v][k].weight && visited[k]==0) //相邻的两个点进行路径大小比较,求出最小路径:逐一比较,保证minpath值为最小值
{
minpath=G->arc[v][k].weight;
j=k;
}
}
if(minpath<max)	//如果存在最小路径,flat++:记录已访问点的个数。visited[j]设为1,表示j点已被访问
{
flat++;
visited[j]=1;
pathsum=pathsum+minpath;						//更新最短路径长度
v=j;				//将点交还给v,以便进行下一次循环:即让现在所在的点成为下一次循环的出发点
printf("->%d",v);//输入该点信息
}
if(flat==n-1)			//当已经访问了所有点,把出发点的visited设为0,即表示未访问,以便寻找并返回正门
{
visited[0]=0;
}
}
printf("->0\n");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: