dijkstra算法

简介:

dijkstra算法是由荷兰计算机科学家dijkstra于1959 年提出的。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。dijkstra算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

缺点:

1. 该算法要求图中不存在负权边。

2. 由于dijkstra算法主要计算从源点到其他所有点的最短路径,所以算法的效率较低。

3. 一次算法不能得到任意两点的最短距离,得到的仅是任意一点到其它任意点的最短距离。

算法流程图:

 算法示例图:

伪代码:

 1  function Dijkstra(G, w, s)
 2     for each vertex v in V[G]                        // 初始化
 3           d[v] := infinity
 4           previous[v] := undefined
 5     d[s] := 0
 6     S := empty set
 7     Q := set of all vertices
 8     while Q is not an empty set                      // Dijstra算法主体
 9           u := Extract_Min(Q)
10           S := S union {u}
11           for each edge (u,v) outgoing from u
12                  if d[v] > d[u] + w(u,v)             // 拓展边(u,v)
13                        d[v] := d[u] + w(u,v)
14                        previous[v] := u

计算复杂度:

行2--4的初始化对n个顶点进行,显然是O(n)
5--6行O(1)
7行n个顶点入队列O(n)
8行--14行,从8行可以看出进行了n遍循环,每遍在第九行调用一次ExtractMin过程,ExtractMin过程需要搜寻邻接表,每一次需要搜寻整个数组,所以一次操作时间是O(n);11行到14行对节点u的邻接表中的边进行检查,总共有|E|次(总共.每条边最多检查一次),因此是O(E);合起来就是O(E+n*n) = O(n^2);

以上合起来就是O(n)+O(1)+O(n)+O(n^2) == O(n^2).

编程实现

#include<stdio.h>
#define POINT_CNT 9

int d[POINT_CNT] = {0};
int p[POINT_CNT] = {0};
int visited[POINT_CNT] = {0};
int w[POINT_CNT][POINT_CNT] = {{0, 2, -1, 9, 6, -1, -1, -1, -1},
  {-1, 0, 1, -1, 3, -1, -1, -1, -1},
  {-1, -1, 0, -1, 1, -1, 6, -1, -1},
  {-1, -1, -1, 0, -1, -1, -1, 4, -1},
  {-1, -1, -1, 2, 0, 9, -1, 7, -1},
  {-1, -1, -1, -1, -1, 0, 5, -1, 1},
  {-1, -1, -1, -1, -1, -1, 0, -1, 5},
  {-1, -1, -1, -1, -1, 1, -1, 0, 5},
  {-1, -1, -1, -1, -1, -1, -1, -1, 0}};

//update the d and p, the distance of point who is near the the_one
void update_d_p(unsigned int the_one)
{
  for (unsigned int i = 0; i < POINT_CNT; i++)
  {
    if (visited[i] == 0 && w[the_one][i] != -1)//i near the_one
    {
      if (d[i] = -1 || d[i] > d[the_one] + w[the_one][i])
      {
        d[i] = d[the_one] + w[the_one][i];
        p[i] = the_one;
      }
    }
  }
}

int get_min_point()
{
  int min = -1;
  int min_point = -1;
  for (unsigned int i = 0; i < POINT_CNT; i++)
  {
    if (visited[i] == 0)
    {
      if (d[i] != -1)
      {
        if (min == -1 || min > d[i])
        {
          min = d[i];
          min_point = i;
        }
      }

    }
  }

  return min_point;
}


int main()
{
  for (unsigned int i = 0; i < POINT_CNT; i++)
  {
    d[i] = -1;
    p[i] = -1;
  }

  d[0] = 0;
  p[0] = -1;
  visited[0] = 1;

  update_d_p(0);

  int min_point = -1;
  while ((min_point = get_min_point()) != -1)
  {
    visited[min_point] = 1;
    update_d_p(min_point);
  }

  for (unsigned int i = 0; i < POINT_CNT; i++)
  {
    printf("d[%d] = %d; ", i, d[i]);
    printf("p[%d] = %d\n", i, p[i]);
  }

  return 0;
}

posted @ 2016-11-13 19:41  米尔克林  阅读(84)  评论(0编辑  收藏  举报