| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2099 人关注过本帖, 1 人收藏
标题:最短路径问题
只看楼主 加入收藏
王谢风流
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2017-12-18
结帖率:100%
收藏(1)
 问题点数:0 回复次数:1 
最短路径问题
总路径表没问题,但是0到1,和1到0的距离,为什么不相同呢
图片附件: 游客没有浏览图片的权限,请 登录注册

图片附件: 游客没有浏览图片的权限,请 登录注册

程序代码:
#include<stdio.h>//标准输入输出函数
#include <stdlib.h>//标准库头文件
#include<string.h>//编译预处理指令
#define OVERFLOW 0//OVERFLOW 溢出
#define MAXSIZE 15
#define MAXINT 9999//最大整数值
#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","a+"))==NULL)
    {
        printf("未找到存储文件,已重新创建,请重新打开本程序");
        exit(1);
    }
    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","a+"))==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");
                scanf("%s",&name);
                printf("请输入要修改后的车位名称\n");
                scanf("%s",&name1);
                UPDATE_park(G, Findpark(G,name),name1);
                printf("修改完成!\n");
            }
            else if(j==2)
            {
                printf("请输入要修改的两个中第一个车位的名称\n");
                scanf("%s",&name);
                printf("请输入要修改的两个中第二个车位的名称\n");
                scanf("%s",&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");
                scanf("%s",&name);
                DELETE_park(G,Findpark(G,name));
                printf("删除完成!\n");
            }
            else if(j==2)
            {
                printf("请输入要删除的路径中第一个车位的名称\n");
                scanf("%s",&name);
                printf("请输入要修改的两个中第二个车位的名称\n");
                scanf("%s",&name);
                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");
                scanf("%s",&name);
                printf("请输入要添加的两个中第二个车位的名称\n");
                scanf("%s",&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:
            return ;
            break;
        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)//ShortestPath最短路径
{
    int i,w,min,l=0;
    int v=1;
    int final[MAXSIZE];//Dijkstra tool
    for(v=1; v<=G->parks;++v)//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(int i=2; i<=G->parks; i++)
    {
        min=MAXINT;
        int v=v0;
        for(int w=1; w<=G->parks; ++w)
        {
            if(!final[w])
            {
                if(D[w]<min)
                {
                    v=w;//u=v
                    min=D[w];//D=dist
                }
            }
        }
        final[v]=TRUE;//final=s
        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 Print1(MGraph *G,int v0)//打印1
{
    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)//打印2
{
    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)//打印3
{
    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("%s",name);
            v0=Findpark(G,name);
           if(v0==-1)
            {
                printf("输入有误或者没有该车位!\n");
                break;
            }
            ShortestPath(G,v0);
            Print1(G,v0);
            break;
        case 2:
            for(j=0; j<G->parks; j++)
            {
                ShortestPath(G,j);
                Print1(G,j);
            }
            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 4:
            Print3(G);
            getchar();
            getchar();
            break;
        case 5:
            return;
        default:
            return ;
        }

    }
}
int main()
{
    MGraph G;
    int password;
    initalize_MGraph(&G);
       menu(0);
       scanf("%d",&password);
       ReadAdjList(&G);
    while(1)
    {
        menu(0);
        scanf("%d",&password);
        if(password==1)
            MODE_ADMIN(&G);
        if(password==2)
            MODE_CLIENT(&G);
        if(password==3)
            return 0;       
    }
    return 0;
}
搜索更多相关主题的帖子: 输入 int list name printf 
2017-12-24 15:02
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
应该是用floyed算法~有向图是可以有不同的~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-12-24 15:11
快速回复:最短路径问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.033904 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved