数据结构——图

一、Dijkstra算法

1. 算法过程

首先定义一个辅助集合 S S S S S S中包括了已经加入到最短路径中的顶点,例如使用一个数组来实现s[]s[i] = 1代表第 i i i个顶点加入到了最短路径。然后定义两个辅助数组:

  • dist[]:记录了从源点 v 0 v_0 v0开始,到剩余顶点的最短路径长度,初值为dist[i] = arcs[0][i]
  • path[]path[i]记录了从源点 v 0 v_0 v0到顶点 v i v_i vi的最短路径的前驱结点,再每次算法结束时,可以回溯 v 0 v_0 v0 v i v_i vi的最短路径。

算法过程:

  • 初始化:集合 S S S初始化为{0},初始化dist[]
  • 从顶点集合 V − S V-S VS中选出 v j v_j vj,满足 d i s t [ j ] = M i n { d i s t [ i ] ∣ v i ∈ V − S } dist[j] = Min\{dist[i] | v_i \in V-S\} dist[j]=Min{dist[i]viVS},这里就得到了一条从 v 0 v_0 v0 v j v_j vj的最短路径。 S = S ∪ j S=S \cup {j} S=Sj
  • 修改从 v 0 v_0 v0出发到 V − S V-S VS任意一点 v k v_k vk的最短路径长度:
    if (dist[j] + arcs[j][k] < dist[k])
    	dist[k] = dist[j] + arcs[j][k];
    
  • 重复上述步骤,直到所有的顶点都在 S S S中。

2. 代码

template <typename T>
void Graph<T>::_dijkstra(int v, int *path, int *shortpath) const {
    bool *visited = new bool [vexnum];
    for (int i = 0; i < vexnum; ++i)
        visited[i] = false;

    visited[v] = true;
    path[v] = -1;
    shortpath[v] = 0;

    int k = v;
    int nextk = -1;
    EdgeNode *p;
    int count = 0;

    for (int i = 1; i < vexnum; ++i) {
        for (p = vexlist[k].first; p; p = p->next) {
            int j = p->adjvex;
            if (!visited[j] && shortpath[j] > shortpath[k] + p->weight)
                shortpath[j] = shortpath[k] + p->weight;
        }
        nextk = _findMinLen(shortpath, visited);    // 查找源点邻点中权值最小的
        if (nextk == -1)
            break;
        else {
            visited[nextk] = true;                  // 将找到的点加入到最短路径中
            path[nextk] = k;
            k = nextk;
            count++;
        }
    }

    std::cout << "shortest path: " << std::endl;
    int lastVer;
    std::stack<int> tmp;
    for (int i = 1; i <= count; ++i) {
        std::cout << shortpath[k] << " : ";

        tmp.push(k);
        lastVer = path[k];
        while (lastVer != v) {
            tmp.push(lastVer);
            lastVer = path[lastVer];
        }
        tmp.push(v);

        std::cout << tmp.top();
        tmp.pop();
        while (!tmp.empty()) {
            std::cout << "->" << tmp.top();
            tmp.pop();
        }
        std::cout << "\n";
        k = path[k];
    }
}

二、Prim算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值