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

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          2147483647
struct 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;
}: 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值