Day12:单源最短路径的C语言实现

1. Dijkstra算法的思想

对于一个图,求从某个顶点出发到其它顶点的最短路径,就是单源最短路径问题。
Dijkstra算法是求单源最短路径的经典算法,它设置以下集合:

  • 真假数组visited:记录已求得和尚未求得最短路径的顶点
    (也可以设置两个顶点集合visited和unvisited)
  • 路径数组dist:记录当前求得到某顶点的最短路径长度
    (某个顶点的visited为真时,dist中对应记录的是最终求得的最短路径)
  • 顶点数组path:记录已经求得最短路径的顶点其前驱结点
    (可用于回溯构建路径)

算法流程如下:

  1. 初始时,设置出发顶点v0已求得,最短路径长为0,前驱顶点为v0
  2. 将dist设置为v0到相邻结点的弧的权值,path设为v0;非相邻结点设为无穷大,path设为-1
  3. 在dist中选择一条最短的路径,对应的vi即求得了最短路径
  4. 更新dist和path,若有value[i][j] + dist[i] < dist[j],说明有更短的路径,修改对应的dist[j]和path[j]
  5. 重复3、4,直到所有的顶点都已经求得最短路径,visited数组全真

2. Dijkstra算法的C语言实现

对Day9的邻接矩阵加以简单改造,使其可以表示带权有向图。

// 只需修改这一函数
void MatrixGraphInserArc(MatrixGraph *mg, char vex1, char vex2, int value)
{
    int vexNo1 = MatrixGraphLocateVex(mg, vex1);
    int vexNo2 = MatrixGraphLocateVex(mg, vex2);
    if(vexNo1 < 0 || vexNo2 < 0)
        return;
    mg->arcs[vexNo1][vexNo2] = value;
    mg->arcNum++;
}

Dijkstra算法的函数如下:

void Dijkstra(MatrixGraph *mg, char startVex, int dist[], int path[])
{
    // 初始设置
    int start = MatrixGraphLocateVex(mg, startVex);
    int *visited = malloc(sizeof(int) * mg->vexNum);
    memset(visited, 0, sizeof(int) * mg->vexNum);
    for(int i = 0;i < mg->vexNum;i++) {
        if(mg->arcs[start][i] == 0) {
            dist[i] = 0x7fffffff;       // int型最大整数
            path[i] = -1;
        }
        else {
            dist[i] = mg->arcs[start][i];
            path[i] = start;
        }
    }
    visited[start] = 1;
    dist[start] = 0;
    path[start] = 0;
    // 贪心选择
    for(int i = 0;i < mg->vexNum - 1;i++) {     // 共进行vexNum - 1次贪心选择
        int minValue = 0x7fffffff;
        int v = -1;
        for(int j = 0;j < mg->vexNum;j++) {     // 找到最短的路径长度
            if(visited[j] == 0 && dist[j] < minValue) {
                v = j;
                minValue = dist[j];
            }
        }
        if(v == -1)
            return;                             // 非连通图,未连通start的最短路径为无穷,前驱为-1
        visited[v] = 1;                         // 当前最短为已经求得
        for(int j = 0;j < mg->vexNum;j++) {     // 更新dist和path
            if(visited[j] == 0 && mg->arcs[v][j] > 0 && mg->arcs[v][j] + dist[v] < dist[j]) {       // 未求得的点,邻接到v且路径更短,则更新
                dist[j] = mg->arcs[v][j] + dist[v];
                path[j] = v;
            }
        }
    }
}

你可能感兴趣的:(复习,数据结构,数据结构,c语言,图论,最短路径)