图的广度优先搜索
描述:
图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接点的邻接点。如此进行下去,直到所有的结点都访问为止。在该题中,假定所有的结点以“A”--“Z”中的若干字符表示,且要求结点的访问顺序要求根据由“A”至“Z”的字典顺序进行访问。例如有如下图:
如果要求从H开始进行广度优先搜索,则搜索结果为:H->A->E->K->U.
输入:
输入只包含一个测试用例,第一行为一个自然数n,表示顶点的个数,第二行为n个大写字母构成的字符串,表示顶点,接下来是为一个n*n大小的矩阵,表示图的邻接关系。数字为0表示不邻接,否则为相应的边的长度。
最后一行为一个字符,表示要求进行广度优先搜索的起始顶点。
输出:
用一行输出广度优先搜索结果,起始点为给定的顶点,各顶点之间用一个空格隔开。要求同一顶点的邻接点的访问顺序按“A”---“Z”的字典顺序。
样例输入:
5
HUEAK
0 0 2 3 0
0 0 0 7 4
2 0 0 0 0
3 7 0 0 1
0 4 0 1 0
H
样例输出:
H A E K U
AC code:
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
using namespace std;
struct ENode
{
int data;
struct ENode *next;
};
typedef struct
{
int flag;
char s;
struct ENode *fc;
}HNode;
HNode *HN,*v;
struct ZZZ{
char s;
int id;
};
ZZZ T[100];
bool cmp(ZZZ a,ZZZ b){
return a.s<b.s;
}
queue <int> Q;
void BFS(int k)
{
ENode *p;
p=HN[k].fc;
HN[k].flag=1;
int j=0,i;
//cout<<HN[k].s;
while(p)
{
if(HN[p->data].flag==0)
{
T[j].id=p->data;
T[j].s=HN[p->data].s;
HN[p->data].flag=1;
j++;
}
p=p->next;
}
sort(T,T+j,cmp);
for(i=0;i<j;i++){
cout<<' '<<T[i].s;
Q.push(T[i].id);
}
if(!Q.empty()){
k=Q.front();
Q.pop();
BFS(k);
}
}
int main()
{
ENode *p;
int n,i,j,e;
while(cin>>n)
{
HN=new HNode[n+1];
for(i=1;i<=n;i++)
{
cin>>HN[i].s;
HN[i].flag=0;
HN[i].fc=NULL;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>e;
if(e)
{
p=new ENode;
p->data=j;
p->next=HN[i].fc;
HN[i].fc=p;
}
}
/* for(i=1;i<=n;i++)
{
ENode *p;
cout<<HN[i].s<<": ";
p=HN[i].fc;
while(p)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}*/
char c;
cin>>c;
int k;
for(j=1;j<=n;j++)
if(HN[j].s==c)
{
k=j;
break;
}
cout<<HN[k].s;
BFS(k);
cout<<endl;
}
return 0;
}
wxl大神代码: http://www.cpproad.com/forum.php?mod=viewthread&tid=488&extra=page%3D1
#include <iostream>
#include <queue>
using namespace std;
int n;
char str[100];
struct Node{
int index; //改点在邻接表中的下标
Node *next;
};
struct kkk{
char s;
bool visited;
Node *first;
}A[100];
struct Temp{
char s;
int id;
};
bool cmp(Temp a,Temp b){
return a.s<b.s;
}
int main(){
char s;
while(cin>>n){
cin>>str;
int i,j,e,k=0;
for(i=0;i<n;i++){//初始化邻接表
A[i].s=str[i];
A[i].visited=false;
A[i].first=NULL;
}
Node *p;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
cin>>e;
if(e){ //构造邻接表
p=new Node;
p->index=j;
p->next=A[i].first;
A[i].first=p;
}
}
}
cin>>s;
for(i=0;i<n;i++){
if(str[i]==s)
break;
}
queue<int> Q;
Q.push(i);
A[i].visited=true;
cout<<str[i];
Temp t[100];
int c,bj=i;
while(!Q.empty()){
c=0;
j=Q.front();
//A[j].visited=true;
if(bj!=j)
cout<<' '<<str[j];
Node *q;
q=A[j].first;
//cout<<q->index<<endl;
while(q){ //找到与该点相连的所有未访问过的结点,保存到数组t中
if(!A[q->index].visited){
A[q->index].visited=true;
t[c].id=q->index;
t[c].s=A[q->index].s;
c++;
}
q=q->next;
}
sort(t,t+c,cmp); //因为要求按字典顺序搜索,所以将t中数据排序一次再入队
for(i=0;i<c;i++)
Q.push(t[i].id);
Q.pop(); //访问过的节点出队
}
cout<<endl;
}
return 0;
}