c語言 圖的最短路徑兩種求法


 

 

 

 

 

 

/* 
 * 最短路徑,迪傑斯特拉算法和弗洛伊德算法(采用鄰接矩陣存儲) 
 * 
 */  
  
#include<stdio.h>  
  
#define MAX_VERTEX_NUM 20  
#define INFINITE 10000  //當做無窮大  
//圖的定義  
typedef struct   
{  
    int vertexNum;  
    char vertex[MAX_VERTEX_NUM];  
    int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  
}Graph,*PGraph;  
  
//輔助數組中的元素定義  
typedef struct  
{  
    int distance;  
    int path[MAX_VERTEX_NUM];  
}ArrayNode;  
  
  
//構造有向網  
void createdGraph(PGraph g)  
{  
    int i,j;  
    g->vertexNum=6;  
    for(i=0;i<g->vertexNum;i++)  
        g->vertex[i]='A'+i;  
    for(i=0;i<g->vertexNum;i++)  
        for(j=0;j<g->vertexNum;j++)  
            g->arc[i][j]=0;  
    g->arc[0][2]=10;  
    g->arc[0][4]=30;  
    g->arc[0][5]=100;  
    g->arc[1][2]=5;  
    g->arc[2][3]=50;  
    g->arc[3][5]=10;  
    g->arc[4][3]=20;  
    g->arc[4][5]=60;  
}  
  
//迪傑斯特拉算法  
void Dijkstra(PGraph g,int from,int to)  
{  
    int i,j,index=-1;  
    int n=1;//記錄已經求出的兩個點之間的最短距離的個數  
    ArrayNode shortestPath[MAX_VERTEX_NUM];  
    int flag[MAX_VERTEX_NUM]={0};//標記,為1表示到這個頂點的最短距離已求出  
  
    //1.求from到各個頂點的直接距離,即初始化shortestPath數組  
    for(i=0;i<g->vertexNum;i++){  
        if(from==i){  
            shortestPath[i].distance=0;  
            shortestPath[i].path[0]=i;  
            flag[from]=1;  
        }  
        else if(g->arc[from][i]>0){  
            shortestPath[i].path[0]=from;  
            shortestPath[i].path[1]=i;  
            shortestPath[i].distance=g->arc[from][i];  
        }else  
            shortestPath[i].distance=INFINITE;  
    }  
    //2.每次求一個最短路徑  
    while(n<g->vertexNum){  
        //選擇shortestPath中距離最小的,求出from到這個頂點的最短路徑  
        index=-1;  
        for(i=0;i<g->vertexNum;i++){  
            if(i==from)  
                continue;  
            if(flag[i]==0 && index==-1 && shortestPath[i].distance!=INFINITE)  
                index=i;  
            if(flag[i]==0 && index!=-1 && shortestPath[i].distance<shortestPath[index].distance)  
                index=i;  
        }  
        flag[index]=1;  
        //修改到各個頂點的最短路徑  
        for(i=0;i<g->vertexNum;i++){  
            if(i==from)  
                continue;  
            if(g->arc[index][i]>0 && g->arc[index][i]+shortestPath[index].distance<shortestPath[i].distance){  
                shortestPath[i].distance=g->arc[index][i]+shortestPath[index].distance;  
                //修改路徑  
                j=0;  
                while(1){  
                    shortestPath[i].path[j]=shortestPath[index].path[j];  
                    if(shortestPath[index].path[j]==index)  
                        break;  
                    j++;  
                }  
                shortestPath[i].path[j+1]=i;  
            }  
        }  
        n++;  
    }  
    //輸出from到to的最短路徑及長度  
    if(shortestPath[to].distance==INFINITE){  
        printf("%c到%c沒有路徑\n",from+'A',to+'A');  
        return;  
    }  
    printf("%c到%c的最短路徑長度是:%d\n",from+'A',to+'A',shortestPath[to].distance);  
    printf("經過的頂點:  ");  
    i=0;  
    while(1){  
        printf("%-3c",shortestPath[to].path[i]+'A');  
        if(shortestPath[to].path[i]==to)  
            break;  
        i++;  
    }  
    printf("\n");  
}  
  
//弗洛伊德算法  
void Floyd(PGraph g,int from,int to)  
{  
    int i,j,k;  
    int shortestPath[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//存儲最短路徑的數組  
    //初始化shortestPath  
    for(i=0;i<g->vertexNum;i++)  
        for(j=0;j<g->vertexNum;j++){  
            if(i==j){  
                shortestPath[i][j]=0;  
                continue;  
            }  
            if(g->arc[i][j]>0)  
                shortestPath[i][j]=g->arc[i][j];  
            else  
                shortestPath[i][j]=INFINITE;  
        }  
    //將各個頂點順次加入,並修改最短路徑  
    for(k=0;k<g->vertexNum;k++){  
        //在i,j之間加入k  
        for(i=0;i<g->vertexNum;i++){  
            for(j=0;j<g->vertexNum;j++){  
                if(shortestPath[i][k]+shortestPath[k][j]<shortestPath[i][j])  
                    shortestPath[i][j]=shortestPath[i][k]+shortestPath[k][j];  
            }  
        }  
    }  
    //輸出最短路徑  
    if(shortestPath[from][to]==INFINITE){  
        printf("%c到%c沒有路徑\n",from+'A',to+'A');  
        return;  
    }  
    printf("%c到%c的最短路徑長度是:%d\n",from+'A',to+'A',shortestPath[from][to]);  
    printf("\n");  
}  
  
void main()  
{  
    Graph graph;  
    char from,to;  
    createdGraph(&graph);  
    printf("請輸入起點終點(如AF,中間不要有空格)\n");  
    scanf("%c%c",&from,&to);  
    printf("\n迪傑斯特拉算法:\n");  
    Dijkstra(&graph,from-'A',to-'A');  
    printf("\n弗洛伊德算法:\n");  
    Floyd(&graph,from-'A',to-'A');  
}  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM