图的搜索技术是图算法领域的核心。许多图算法的开始,都是通过搜索输入的图来获取图结构信息,另外还有些图的算法实
广度优先搜索的执行方法:从任意点s出发,先遍历与s相邻的点,然后再遍历于相邻的点相邻的点。注意有向图必须是顺方向的邻接点。详细方法,参考任何数据结构书吧。不赘述了。
为什么说广度优先搜索可以用来求无权最短路径呢?因为,广度优先搜索每次都会先发现距离s为k的所有顶点,然后才会
广度优先搜索的实现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|次,即变长,
打印最短路径:
void PrintPath(Graph& g, Vertex& target)
{
if (target.path is a vertex)
{
PrintPath(g, target.path);
}
cout << target;
}
代码实现,为方便,仍然利用之前的有向图例子,但BFS算法对无相图也有效,只要注意修改图结构生成方式就好。
#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;
}