Dijkstra算法

Dijkstra算法
基本算法:
将图G中所有的顶点V分成两个顶点集合A,B.如果源点S到顶点u的最短路径已经知道,则点u属于集合A,否则属于集合B。在最开始的时候A中只包含源点S,其余的点属于B,算法结束时,所有源点S可以达到的点都在集合A中,而不可达的点仍然在集合B。

伪代码:
S为源点,Belong[ ]记录点属于哪个集合,true表示属于A,false表示属于B,map[ ][ ] 记录地图信息,map[u][v]代表点v到点u的长度,最短结果保存到dist[ ]中,pre[ ]记录最短路径终点的前驱,如:到达点j最短的路径上,终点j的前一节点即为k,即pre[j] = k。

  1. 初始化:源点的距离dist[s]设为0,其他的点的距离设为map[s][i],p[s] = true,其他各点的 p[i] = false;
  2. 循环N-1次:
    1. 在B中的点取一s到其距离最小的点k,p[k] = true; 如果所有的k都不可达,退出循环,算法结束。
    2. 对于每个与k相邻的在B中的点j,更新s到j的最短路径,如果dist[k] + map[k][j] < dist[j] ;
      那么dist[j] = dist[k] + map[k][j];

直接实现:
最简单的实现方法是,存储图的信息使用邻接矩阵,在每次循环中,在用一个循环找距离最短的点,然后用遍历的方法更新与其相邻的边,注意比较可以发现,除了路径记录和更新dist数组部分以外,Dijkstra和Prim算法实现完全相同。
样例代码:

const int maxn = 10001;      //点个数
void Dijkstra(int map[maxn][maxn],int s)
// n个点,dist[i]表示点i到源点s的最短距离,map记录图信息,pre记录前驱,源点,终点。
{
    int i, j, k;
    int min;
    bool belone[maxn];         //true 属于A,false属于B
    int dist[maxn];
    int pre[maxn];
    for (i = 1; i < maxn; ++i)   //初始化
    {
        belone[i] = false;
        if (i != s)
        {
            dist[i] = map[s][i];
            pre[i] = s;
        }
    }
    dist[s] = 0;
    belone[s] = true;
    for (i = 1; i < maxn - 1; ++i)//循环n-1次,求s到其他n-1个点的最短路径
    {
        min = INT_MAX;
        k = 0;
        for (j = 1; j < maxn; ++j)//在b中取一点,s到其距离最短
        {
            if (!belone[j] && dist[j] < min)
            {
                min = dist[j];
                k = j;
            }
        }
        if (k == 0) return;     //如果没有点可扩展,即剩余的点不可到达返回
        belone[k] = true;       //将k从B中除去,加入到A
        for (j = 1; j < maxn; ++j)
        {
            //对于每个与k相邻的在B中的点j,更新s到j的最短路径
            if (!belone[j] && map[k][j] != INT_MAX&&dist[j] > dist[k] + map[k][j])
            {
                dist[j] = dist[k] + map[k][j];
                pre[j] = k;
            }
        }
    }
}

效率:时间复杂度为O(n^2),空间复杂度:由于使用邻接矩阵,空间消耗为O(n^2)。

这里写图片描述

输出结果:

这里写图片描述

数据结构习题Dijkstra 1.3、将二叉树看作图,并对它作图的深度优先遍历,则与原二叉树的 结果是相同的。 A、前序遍历 B、中序遍历C、后序遍历D、层次序遍历 1.4、在关于树的以下4种叙述中,正确的是 。 A、用指针方式存储有n个结点的二叉树,至少要有n+1个指针。 B、m阶B-树中,具有k个子结点的结点,必有k-1个键值。 C、m阶B-树中,每个非叶子结点的子结点个数≥[m/2]。 D、平衡树一定是丰满树。 1.5、在最好和最坏情况下的时间复杂度均为O(nlog2n)且稳定的排序方法是 A、希尔排序 B、快速排序 C、堆排序 D、归并排序 二、解答题 2.1、对目标串 abaabcc和模式串aabc,描述根据KMP算法进行匹配的过程,包括失效函数计算。答:失效函数:-1, 0, -1, -1 目标串 abaabcc和模式串aabc的KMP算法进行匹配的过程 abaabcc aabc 首先,从目标位置0和模式位置0开始比较,至ab和aa,不等时目标位置为1, 模式位置为1。因0位置失效函数的值( f [posP-1] ) 为-1,从目标位 置1和模式位置0开始新一轮比较。因第一个字符( posP == 0 )就不等,目标 位置增1,目标位置2和模式位置0开始新一轮比较,直到模式位置比较至4, 匹配成功。 int fastFind ( char *s, char * pat ){ //带失效函数的KMP匹配算法 int posP = 0, posT = 0; int lengthP = strlen(pat), lengthT = strlen(s); while ( posP < lengthP && posT < lengthT ) if ( pat[posP] == s[posT] ) { posP++; posT++; //相等继续比较 } else if ( posP == 0 ) posT++; //不相等 else posP = f [posP-1]+1; if ( posP < lengthP ) return -1; else return posT - lengthP; }
### Dijkstra算法简介 Dijkstra算法是一种用于解决单源最短路径问题的经典算法,适用于带权重的有向图或无向图中的最短路径计算[^1]。该算法的核心思想是从起始节点出发,逐步扩展已知距离最小的未访问节点,并更新其邻居节点的距离。 --- ### Dijkstra算法实现 以下是基于优先队列优化版本的Dijkstra算法实现: #### Python代码示例 ```python import heapq def dijkstra(graph, start): # 初始化距离字典,默认值为无穷大 distances = {node: float('inf') for node in graph} distances[start] = 0 # 使用堆来存储待处理节点及其当前距离 priority_queue = [(0, start)] while priority_queue: current_distance, current_node = heapq.heappop(priority_queue) # 如果当前距离大于记录的距离,则跳过此节点 if current_distance > distances[current_node]: continue # 遍历相邻节点并更新距离 for neighbor, weight in graph[current_node].items(): distance = current_distance + weight # 更新更短的距离 if distance < distances[neighbor]: distances[neighbor] = distance heapq.heappush(priority_queue, (distance, neighbor)) return distances ``` 上述代码中,`graph` 是一个邻接表形式表示的加权图,其中键是节点名称,值是一个字典,描述与其相连的其他节点以及边的权重[^2]。 --- ### Dijkstra算法的应用场景 1. **网络路由协议** 在计算机网络中,路由器可以利用Dijkstra算法找到到达目标地址的最佳路径,从而提高数据传输效率[^3]。 2. **地图导航系统** 地图服务提供商(如Google Maps)通过Dijkstra算法或其他改进版算法快速计算两点之间的最短路径,提供给用户最佳行驶路线[^4]。 3. **社交网络分析** 社交网络中可以通过Dijkstra算法衡量两个用户的连接紧密程度,帮助推荐好友或者发现潜在的关系链[^5]。 4. **物流配送规划** 物流公司使用类似的最短路径算法优化货物运输线路,减少成本和时间消耗[^6]。 --- ### 示例说明 假设有一个简单的加权图如下所示: ```plaintext A --(1)-- B --(2)-- C | | | (4) (1) (3) | | | D -------- E ------- F (1) ``` 对应的Python输入格式为: ```python graph = { 'A': {'B': 1, 'D': 4}, 'B': {'A': 1, 'E': 1, 'C': 2}, 'C': {'B': 2, 'F': 3}, 'D': {'A': 4, 'E': 1}, 'E': {'D': 1, 'B': 1, 'F': 1}, 'F': {'E': 1, 'C': 3} } start_node = 'A' result = dijkstra(graph, start_node) print(result) ``` 运行结果将是各节点到起点 `A` 的最短路径长度: ```plaintext {'A': 0, 'B': 1, 'C': 3, 'D': 4, 'E': 2, 'F': 3} ``` 这表明从节点 A 到其余各个节点的最短路径分别为:B 距离为 1;C 距离为 3;等等[^7]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值