无权最短路径的求法--图的广度优先搜索

来源:互联网 发布:广联达软件购买 编辑:程序博客网 时间:2024/05/21 15:43

http://blog.csdn.net/midgard/article/details/4141087

图的搜索技术是图算法领域的核心。许多图算法的开始,都是通过搜索输入的图来获取图结构信息,另外还有些图的算法实

际上是通过图搜索算法经过简单扩展而成的。
广度优先搜索的执行方法:从任意点s出发,先遍历与s相邻的点,然后再遍历于相邻的点相邻的点。注意有向图必须是顺方向的邻接点。详细方法,参考任何数据结构书吧。不赘述了。
为什么说广度优先搜索可以用来求无权最短路径呢?因为,广度优先搜索每次都会先发现距离s为k的所有顶点,然后才会
发现距离s为k+1的所有顶点。 s为起始点。
      广度优先搜索的实现breadth-frist search:
      对每个distance 变化的顶点入队, 直到剩下的INFINITY顶点没有,遍历结束。
 
void BFS(Graph& g, Vertex& s) {  queue<vertex> q;  for each vertex v in g  {   v.distance = INFINITY;  }  s.distance = 0;    q.enqueue(s);  while (!q.Empty())  {   v = dequeue(q);   for each w adjenct to v   if (v.distance == INFINITY)   {    w.distance = v. distance + 1;           w.path = v;    q.enqueue(w);   }      }     }


 对于外面的while循环,会执行|V|次,因为每个顶点入队出队一次,而里面的for循环会看到一共会执行|E|次,即变长,
所以该算法时间复杂度为O(|V|+|E|)。
 打印最短路径:
 void PrintPath(Graph& g, Vertex& target) {  if (target.path is a vertex)  {   PrintPath(g, target.path);  }  cout << target; }


 代码实现,为方便,仍然利用之前的有向图例子,但BFS算法对无相图也有效,只要注意修改图结构生成方式就好。
#include <iostream>#include <queue>using namespace std;#define MAX_VERTEX_NUM    20#define INFINITY          2147483647struct adjVertexNode {    int adjVertexPosition;    adjVertexNode* next; };struct VertexNode{    char data[2];    adjVertexNode* list;    int distance;    VertexNode* path;}; struct Graph{    VertexNode VertexNode[MAX_VERTEX_NUM];    int vertexNum;    int edgeNum;};void CreateGraph (Graph& g){     int i, j, edgeStart, edgeEnd;     adjVertexNode* adjNode;     cout << "Please input vertex and edge num (vnum enum):" <<endl;     cin >> g.vertexNum >> g.edgeNum;     cout << "Please input vertex information (v1)/n note: every vertex info end with Enter" <<endl;     for (i=0;i<g.vertexNum;i++)      {         cin >> g.VertexNode[i].data; // vertex data info.         g.VertexNode[i].list = NULL;          g.VertexNode[i].path = NULL;     }     cout << "input edge information(start end):" <<endl;     for (j=0; j<g.edgeNum; j++)      {          cin >>edgeStart >>edgeEnd;          adjNode = new adjVertexNode;          adjNode->adjVertexPosition = edgeEnd-1; // because array begin from 0, so it is j-1         adjNode->next=g.VertexNode[edgeStart-1].list;          g.VertexNode[edgeStart-1].list=adjNode;      }}void PrintAdjList(const Graph& g){    cout << "The adjacent list for graph is:" << endl;     for (int i=0; i < g.vertexNum; i++)    {        cout<< g.VertexNode[i].data << "->";        adjVertexNode* head = g.VertexNode[i].list;        if (head == NULL)            cout << "NULL";        while (head != NULL)        {            cout << head->adjVertexPosition + 1 <<" ";            head = head->next;        }        cout << endl;    }}void DeleteGraph(Graph &g){    for (int i=0; i<g.vertexNum; i++)    {        adjVertexNode* tmp=NULL;        while(g.VertexNode[i].list!=NULL)        {            tmp = g.VertexNode[i].list;            g.VertexNode[i].list = g.VertexNode[i].list->next;            delete tmp;            tmp = NULL;        }    }}void BFS(Graph& g, VertexNode& s){    queue<VertexNode*> q;    for (int i=0; i<g.vertexNum; i++)    {        g.VertexNode[i].distance = INFINITY;    }    s.distance = 0;    q.push(&s);    //cout << q.back().data << " " ;    while (!q.empty())    {        VertexNode* v = q.front();        q.pop();        adjVertexNode* head = v->list;        while (head != NULL)        {            if (g.VertexNode[head->adjVertexPosition].distance == INFINITY)            {                g.VertexNode[head->adjVertexPosition].distance = v->distance + 1;                                            g.VertexNode[head->adjVertexPosition].path = v;                q.push(&g.VertexNode[head->adjVertexPosition]);                //cout << q.back().data << " " ;            }            head = head->next;        }    }        }void PrintPath(Graph& g, VertexNode* target){    if (target->path != NULL)    {        //cout << 1 << " ";        PrintPath(g, target->path);        cout << " ";    }    cout << target->data ;}int main(int argc, const char** argv){    Graph g;    CreateGraph(g);    PrintAdjList(g);    BFS(g, g.VertexNode[0]);    cout<<"print the shortest path from v1 to v7:"<<endl;    PrintPath(g, &g.VertexNode[6]);    DeleteGraph(g);    return 0;}: