Dijkstra和Floyd算法

陌路散爱 提交于 2019-12-28 11:34:04
#include

#include

#include

#define Infinity 999  //最大值

#define Max_Vertex_Num 20  //顶点数最多为20

#define Len sizeof(struct arcNode)

#define gLen sizeof(struct Graph)

#define HIT_Ver_Num 11  //共有11个顶点

#define HIT_Arc_Num 18  //共有18个边

//边节点

struct arcNode{

    int adjvex;  //该边所指向的顶点位置

    struct arcNode *nextArc;  //指向下一条边的指针

    int value;  //边的权值

};

//顶点节点

typedef struct verNode{

    char *data;  //顶点信息

    struct arcNode *firstArc;  //指向第一条依附该顶点的边

}verNode,adjList[Max_Vertex_Num];

//图的邻接表存储类型

struct Graph{

    int g_arcs[Max_Vertex_Num][Max_Vertex_Num];

    adjList vertices;  //声明一个存储顶点的数组

    int vexNum,arcNum;  //vexNum 是顶点数,arcNum 是边数

};

struct Graph * creatGraph()

{

    int i,j,a,b;

    struct Graph *graph = (struct Graph *)malloc(gLen);

    struct arcNode *arc_1 = (struct arcNode *)malloc(Len);//N楼

    struct arcNode *arc_2 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_3 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_4 = (struct arcNode *)malloc(Len);//食堂

    struct arcNode *arc_5 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_6 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_7 = (struct arcNode *)malloc(Len);//教师公寓

    struct arcNode *arc_8 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_9 = (struct arcNode *)malloc(Len);//M楼

    struct arcNode *arc_10 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_11 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_12 = (struct arcNode *)malloc(Len);//G楼

    struct arcNode *arc_13 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_14 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_15 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_16 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_17 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_18 = (struct arcNode *)malloc(Len);//主楼

    struct arcNode *arc_19 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_20 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_21 = (struct arcNode *)malloc(Len);//H楼

    struct arcNode *arc_22 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_23 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_24 = (struct arcNode *)malloc(Len);//体育场

    struct arcNode *arc_25 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_26 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_27 = (struct arcNode *)malloc(Len);//校训石

    struct arcNode *arc_28 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_29 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_30 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_31 = (struct arcNode *)malloc(Len);//研究院

    struct arcNode *arc_32 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_33 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_34 = (struct arcNode *)malloc(Len);//学校正门

    struct arcNode *arc_35 = (struct arcNode *)malloc(Len);

    struct arcNode *arc_36 = (struct arcNode *)malloc(Len);

    char *Data[HIT_Ver_Num] = {"N楼","食堂","教师公寓","M楼","G楼","主楼","H楼","体育场","校训石","研究院","学校正门"};

    if(graph==NULL||arc_1==NULL||arc_2==NULL||arc_3==NULL||arc_4==NULL||arc_5==NULL||arc_6==NULL||arc_7==NULL||arc_8==NULL||arc_9==NULL

       ||arc_10==NULL||arc_11==NULL||arc_12==NULL||arc_13==NULL||arc_14==NULL||arc_15==NULL||arc_16==NULL||arc_17==NULL||arc_18==NULL

       ||arc_19==NULL||arc_20==NULL||arc_21==NULL||arc_22==NULL||arc_23==NULL||arc_24==NULL||arc_25==NULL||arc_26==NULL||arc_27==NULL

       ||arc_28==NULL||arc_29==NULL||arc_30==NULL||arc_31==NULL||arc_32==NULL||arc_33==NULL||arc_34==NULL||arc_35==NULL||arc_36==NULL)

       {

           printf("内存不足\n退出程序");

           exit(0);

       }

 

    graph->vexNum = HIT_Ver_Num;

    graph->arcNum = HIT_Arc_Num;

    for(j = 0; j < graph->vexNum; j++)

    {

        graph->vertices[j].data = Data[j];

        graph->vertices[j].firstArc = NULL;

    }

 

    arc_1->value = 130;

    arc_1->adjvex = 3;

    arc_1->nextArc = graph->vertices[0].firstArc;

    graph->vertices[0].firstArc = arc_1;

 

    arc_2->value = 140;

    arc_2->adjvex = 4;

    arc_2->nextArc = graph->vertices[0].firstArc;

    graph->vertices[0].firstArc = arc_2;

 

    arc_3->value = 55;

    arc_3->adjvex = 1;

    arc_3->nextArc = graph->vertices[0].firstArc;

    graph->vertices[0].firstArc = arc_3;//End N楼

 

    arc_4->value = 55;

    arc_4->adjvex = 0;

    arc_4->nextArc = graph->vertices[1].firstArc;

    graph->vertices[1].firstArc = arc_4;

 

    arc_5->value = 150;

    arc_5->adjvex = 4;

    arc_5->nextArc = graph->vertices[1].firstArc;

    graph->vertices[1].firstArc = arc_5;

 

    arc_6->value = 110;

    arc_6->adjvex = 2;

    arc_6->nextArc = graph->vertices[1].firstArc;

    graph->vertices[1].firstArc = arc_6;//End 食堂

 

    arc_7->value = 110;

    arc_7->adjvex = 1;

    arc_7->nextArc = graph->vertices[2].firstArc;

    graph->vertices[2].firstArc = arc_7;

 

    arc_8->value = 105;

    arc_8->adjvex = 6;

    arc_8->nextArc = graph->vertices[2].firstArc;

    graph->vertices[2].firstArc = arc_8;//End 教师公寓

 

    arc_9->value = 130;

    arc_9->adjvex = 0;

    arc_9->nextArc = graph->vertices[3].firstArc;

    graph->vertices[3].firstArc = arc_9;

 

    arc_10->value = 40;

    arc_10->adjvex = 4;

    arc_10->nextArc = graph->vertices[3].firstArc;

    graph->vertices[3].firstArc = arc_10;

 

    arc_11->value = 70;

    arc_11->adjvex = 7;

    arc_11->nextArc = graph->vertices[3].firstArc;

    graph->vertices[3].firstArc = arc_11;//End M楼

 

    arc_12->value = 40;

    arc_12->adjvex = 3;

    arc_12->nextArc = graph->vertices[4].firstArc;

    graph->vertices[4].firstArc = arc_12;

 

    arc_13->value = 140;

    arc_13->adjvex = 0;

    arc_13->nextArc = graph->vertices[4].firstArc;

    graph->vertices[4].firstArc = arc_13;

 

    arc_14->value = 150;

    arc_14->adjvex = 1;

    arc_14->nextArc = graph->vertices[4].firstArc;

    graph->vertices[4].firstArc = arc_14;

 

    arc_15->value = 40;

    arc_15->adjvex = 5;

    arc_15->nextArc = graph->vertices[4].firstArc;

    graph->vertices[4].firstArc = arc_15;

 

    arc_16->value = 100;

    arc_16->adjvex = 8;

    arc_16->nextArc = graph->vertices[4].firstArc;

    graph->vertices[4].firstArc = arc_16;

 

    arc_17->value = 65;

    arc_17->adjvex = 7;

    arc_17->nextArc = graph->vertices[4].firstArc;

    graph->vertices[4].firstArc = arc_17;//End G楼

 

    arc_18->value = 40;

    arc_18->adjvex = 4;

    arc_18->nextArc = graph->vertices[5].firstArc;

    graph->vertices[5].firstArc = arc_18;

 

    arc_19->value = 115;

    arc_19->adjvex = 6;

    arc_19->nextArc = graph->vertices[5].firstArc;

    graph->vertices[5].firstArc = arc_19;

 

    arc_20->value = 50;

    arc_20->adjvex = 8;

    arc_20->nextArc = graph->vertices[5].firstArc;

    graph->vertices[5].firstArc = arc_20;//End 主楼

 

    arc_21->value = 105;

    arc_21->adjvex = 2;

    arc_21->nextArc = graph->vertices[6].firstArc;

    graph->vertices[6].firstArc = arc_21;

 

    arc_22->value = 115;

    arc_22->adjvex = 5;

    arc_22->nextArc = graph->vertices[6].firstArc;

    graph->vertices[6].firstArc = arc_22;

 

    arc_23->value = 60;

    arc_23->adjvex = 9;

    arc_23->nextArc = graph->vertices[6].firstArc;

    graph->vertices[6].firstArc = arc_23;//End H楼

 

    arc_24->value = 70;

    arc_24->adjvex = 3;

    arc_24->nextArc = graph->vertices[7].firstArc;

    graph->vertices[7].firstArc = arc_24;

 

    arc_25->value = 65;

    arc_25->adjvex = 4;

    arc_25->nextArc = graph->vertices[7].firstArc;

    graph->vertices[7].firstArc = arc_25;

 

    arc_26->value = 100;

    arc_26->adjvex = 10;

    arc_26->nextArc = graph->vertices[7].firstArc;

    graph->vertices[7].firstArc = arc_26;//End 体育场

 

    arc_27->value = 100;

    arc_27->adjvex = 4;

    arc_27->nextArc = graph->vertices[8].firstArc;

    graph->vertices[8].firstArc = arc_27;

 

    arc_28->value = 50;

    arc_28->adjvex = 5;

    arc_28->nextArc = graph->vertices[8].firstArc;

    graph->vertices[8].firstArc = arc_28;

 

    arc_29->value = 50;

    arc_29->adjvex = 9;

    arc_29->nextArc = graph->vertices[8].firstArc;

    graph->vertices[8].firstArc = arc_29;

 

    arc_30->value = 40;

    arc_30->adjvex = 10;

    arc_30->nextArc = graph->vertices[8].firstArc;

    graph->vertices[8].firstArc = arc_30;//End 校训石

 

    arc_31->value = 50;

    arc_31->adjvex = 8;

    arc_31->nextArc = graph->vertices[9].firstArc;

    graph->vertices[9].firstArc = arc_31;

 

    arc_32->value = 60;

    arc_32->adjvex = 6;

    arc_32->nextArc = graph->vertices[9].firstArc;

    graph->vertices[9].firstArc = arc_32;

 

    arc_33->value = 70;

    arc_33->adjvex = 10;

    arc_33->nextArc = graph->vertices[9].firstArc;

    graph->vertices[9].firstArc = arc_33;//End 研究院

 

    arc_34->value = 100;

    arc_34->adjvex = 7;

    arc_34->nextArc = graph->vertices[10].firstArc;

    graph->vertices[10].firstArc = arc_34;

 

    arc_35->value = 40;

    arc_35->adjvex = 8;

    arc_35->nextArc = graph->vertices[10].firstArc;

    graph->vertices[10].firstArc = arc_35;

 

    arc_36->value = 70;

    arc_36->adjvex = 9;

    arc_36->nextArc = graph->vertices[10].firstArc;

    graph->vertices[10].firstArc = arc_36;//End 学校正门

 

    for(a = 0; a < graph->vexNum; a++)  //置为无穷大(999)

    {

        for(b = 0; b < graph->vexNum; b++)

        {

            graph->g_arcs[a][b] = Infinity;

        }

    }

    for(i = 0; i < graph->vexNum; i++)  //将相应位置置权值

    {

        while(graph->vertices[i].firstArc != NULL)

        {

            graph->g_arcs[i][graph->vertices[i].firstArc->adjvex] = graph->vertices[i].firstArc->value;

            graph->vertices[i].firstArc = graph->vertices[i].firstArc->nextArc;

        }

    }

    return graph;

}

//单源最短路径(即 Dijkstra算法)

void shortestPath_Dij(struct Graph graph,int v0)

{

    int i = 0,v,w,min,pre;

    int arrayD[HIT_Ver_Num],arrayP[HIT_Ver_Num];//辅助数组

    int arrayFinal[HIT_Ver_Num];//辅助数组

    //初始化

    for(v = 0; v < graph.vexNum; v++)

    {

        arrayFinal[v] = 0;

        arrayD[v] =graph.g_arcs[v0][v];

        if(arrayD[v] < Infinity)

        {

            arrayP[v] = v0;

        }

        else

        {

            arrayP[v] = -1;

        }

    }

    arrayFinal[v0] = 1;

    arrayP[v0] = -1;

    for(i = 1; i < graph.vexNum; i++)

    {

        min = Infinity;

        //加入具有最小代价的邻居节点

        for(w = 0; w < graph.vexNum; w++)

        {

            if(!arrayFinal[w] && (arrayD[w] < min))

            {

                v = w;

                min = arrayD[w];

            }

        }

        arrayFinal[v] = 1;

        //计算加入新的节点后,更新路径使得其产生代价最短

        for(w = 0; w < graph.vexNum; w++)

        {

            if(!arrayFinal[w] && (min + graph.g_arcs[v][w] < arrayD[w]))

            {

                arrayD[w] = min + graph.g_arcs[v][w];

                arrayP[w] = v;

            }

        }

    }

    for(i = 0; i < graph.vexNum; i++)

    {

        if(v0 == i)

            printf("目的地与起点重合,权值为零\n\n");

        else

        {

            printf("权值为:%d\n",arrayD[i]);

            printf("%s",graph.vertices[i].data);

            pre = arrayP[i];

            while(pre != -1)

            {

                printf(" <-- %s",graph.vertices[pre].data);

                pre = arrayP[pre];

            }

            printf("\n\n");

        }

    }

}

void shortestPath_Floyd(struct Graph graph,int v1,int v2)

{

    int i,j,k,temp;

    int arrayPath[HIT_Ver_Num][HIT_Ver_Num],arrayDis[HIT_Ver_Num][HIT_Ver_Num];

    //初始化

    for(i = 0; i < graph.vexNum; i++)

    {

        for(j = 0; j < graph.vexNum; j++)

        {

            if(graph.g_arcs[i][j] < Infinity)

                arrayPath[i][j] = j;

            else

                arrayPath[i][j] = -1;

            arrayDis[i][j] = graph.g_arcs[i][j];

        }

    }

 

    for(k = 0; k < graph.vexNum; k++)//对所有顶点进行试探

    {

        for(i = 0; i < graph.vexNum; i++)

        {

            for(j = 0; j < graph.vexNum; j++)

            {

                if(arrayDis[i][j] > arrayDis[i][k] + arrayDis[k][j])

                {

                    arrayDis[i][j] = arrayDis[i][k] + arrayDis[k][j];//取较小者

                    arrayPath[i][j] = arrayPath[i][k];//改Vi的后继

                }

            }

        }

    }

 

    printf("从 %s 到 %s 的最短距离为:%d\n",graph.vertices[v1].data,graph.vertices[v2].data,arrayDis[v1][v2]);

    printf("最短路径为:\t");

    temp = arrayPath[v1][v2];

    printf("%s --> ",graph.vertices[v1].data);//输出V1

    while(temp != v2)//temp不等于路径终点v2时

    {

        printf("%s --> ",graph.vertices[temp].data);//输出

        temp = arrayPath[temp][v2];//求路径上下一顶点

    }

    printf("%s.",graph.vertices[v2].data);//输出V2

    printf("\n");

}

int main()

{

    int b,c,count = 0;

    int num,i,a,i_2,i_3;

    char *nodeName_1 = (char*)malloc(10);//必须得用malloc函数申请空间

    char *nodeName_2 = (char*)malloc(10);//必须得用malloc函数申请空间

    char *nodeName_3 = (char*)malloc(10);//必须得用malloc函数申请空间

    struct Graph *graph;

    graph = creatGraph();  //生成图

    for(b=0;bvexNum;b++)

    {

        for(c = 0;cvexNum;c ++)

        {

            printf("%d\t",graph->g_arcs[b][c]);

        }

        printf("\n");

    }

 

    printf("请按提示进行操作:\n");

    printf("1、输入任意一个节点的名称,显示它到各个节点的最短路径及最短距离。\n");

    printf("2、输入任意两个节点的名称,显示两点间最短路径和最短距离。\n");

    printf("请输入 1 或 2 进行查询。\n");

    scanf("%d",&num);

    switch(num)

    {

        case 1:

            for(a = 0;avexNum;a++)

            {

                printf("%s ",graph->vertices[a].data);

            }

            printf("\n");

            printf("请输入节点名称:\n");

            scanf("%s",nodeName_1);

            for(i = 0; i < graph->vexNum; i++)

            {

                if(strcmp(nodeName_1,graph->vertices[i].data) != 0)

                {

                    count++;

                }

                if(0 == strcmp(nodeName_1,graph->vertices[i].data))

                {

                    shortestPath_Dij(*graph,i);

                }

            }

            if(graph->vexNum == count)

            {

                printf("输入名称有误!退出程序!");

                exit(0);

            }

        break;

        case 2:

            for(a = 0;avexNum;a++)

            {

                printf("%s ",graph->vertices[a].data);

            }

            printf("\n");

            printf("请分别输入第一个节点名称:\n");

            scanf("%s",nodeName_2);

            printf("请分别输入第二个节点名称:\n");

            scanf("%s",nodeName_3);

            for(i = 0; i < graph->vexNum; i++)

            {

                if(0 == strcmp(nodeName_2,graph->vertices[i].data))

                {

                    i_2 = i;

                }

                if(0 == strcmp(nodeName_3,graph->vertices[i].data))

                {

                    i_3 = i;

                }

            }

            if(i_2 == i_3)

            {

                printf("输入的起点和终点重合,退出程序!");

                exit(0);

            }

            shortestPath_Floyd(*graph,i_2,i_3);

        break;

        default:

            printf("输入有误!退出程序!");

            exit(0);

        break;

    }

    return 0;

}

  


实验结果:


 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!