考研数据结构之dijkstra核心代码实现cpp

代码

本文使用vetor模拟邻接表,可以直接用二维数组

void print_path(int path[], int a)
{
    // path实际是一个双亲存储结构的树
    // 只能从叶子节点找到根节点
    // 因此需要一个栈,将序列倒着输出,即为从根节点到叶子节点
    stack<int> s;
    
    while (path[a] != -1) // 一直向上直到查找到根节点
    {
        s.push(a);  // 思考一下如果这两句交换位置会怎么样?
        a = path[a];
    }

    while (!s.empty())
    {
        cout << s.top() << " ";
    }

    cout << endl;
}

struct node {
    int to, cost;
};
vector <node> G[MAXN];
int vis[MAXN]; // 标记节点是否已经加入到最短路中
int dis[MAXN]; // 当前源点到i的最短距离
int path[MAXN];  // path[i] = j,代表从源点到i的上一步是j

void dijkstra(int v, int n)
{
    // 初始化三个数组
    for (int i=0; i<n; i++)
    {
        dis[i] = INF;
        vis[i] = 0;
        path[i] = -1;
    }

    // 把与源点直连的节点的距离在dis数组中更新
    // 并且路径数组中进行更新
    for (int i=0; i<G[v].size(); i++)
    {
        dis[G[v][i].to] = G[v][i].cost;
        path[G[v][i].to] = v;
    }

    vis[v] = 1;  // 代表已经访问过v

    // 将剩下的n-1个节点依次加入到最短路中
    for (int i=0; i<n-1; i++)
    {
        int index = 0, min = INF;

        // 查找当前dis中最短的路径,记下节点编号
        for (int j=0; j<n; j++)
        {
            if (!vis[j] && dis[j] < min)
            {
                index = j;
                min = dis[j];
            }
        }

        vis[index] = 1; // 将找到的节点加入到最短路中

        // 通过新加入的节点进行更新dis数组
        for (int j=0; j<G[index].size(); j++)
        {
            // 如果当前从源点到j的距离大于源点到index+index到j的距离,更新dis数组
            if (!vis[G[index][j].to] && dis[j] < dis[index] + G[index][j].cost)
            {
                dis[j] = dis[index] + G[index][j].cost;
                path[j] = index;  // 前驱为index
            }
        }
    }
}
上一篇:Dijkstra算法(C/C++)


下一篇:图的最短路径(Dijkstra)(Floyd),拓扑排序,生成树代码