邻接表:深度优先遍历和广度优先遍历
9天没有摸C语言,手很生啊!
唉,考试终于结束了,就剩三门了。
算法、数据结构太重要了,不要忽视啊!
#include <bits/stdc++.h>
using namespace std;
#define MAXSIZE 100
int v[MAXSIZE];//标志位,判断该结点有没有被访问
typedef struct ArcNode //定义表节点
{
int adjvex;
struct ArcNode *next;
}ArcNode;
typedef struct VNode //定义头结点
{
int data;
ArcNode *firstarc;
}VNode,AdjList[MAXSIZE];
typedef struct //定义图的整体数据结构
{
int vexnum,arcnum;//边数、弧数
AdjList vertices;
}ALGraph;
void Init(ALGraph &G)//初始化无向图
{
int i,n,m,a,b;
ArcNode *s;
cin>>n>>m;
G.arcnum=m;
G.vexnum=n;
for(i=1;i<=G.vexnum;i++)//初始化
{
G.vertices[i].firstarc=NULL;//一开始都指向NULL
G.vertices[i].data=i;//初始化节点编号从1~n
}
for(i=0;i<G.arcnum;i++)
{
cin>>a>>b;
/*a指向b*/
s=new ArcNode[sizeof(ArcNode)];
s->adjvex=b;
s->next=G.vertices[a].firstarc;
G.vertices[a].firstarc=s;
/*b指向a*/
s=new ArcNode[sizeof(ArcNode)];
s->adjvex=a;
s->next=G.vertices[b].firstarc;
G.vertices[b].firstarc=s;
}
}
int FirstAdjVex(ALGraph G,int k)//返回图G中与k相邻且未被访问过的点的编号,如果不存在这样的点返回-1
{
ArcNode *s;
s=G.vertices[k].firstarc;
if(!s)
return -1;
while(s&&v[s->adjvex])//如果不空又访问过,就看下一个
s=s->next;
if(s)//不空说明找到了
return s->adjvex;
else//否则返回-1
return -1;
}
int NextAdjVex(ALGraph G,int k,int w)//返回图G中与k相邻、除了编号是w之外的未被访问过的点的编号,如果不存在这样的点返回-1
{
ArcNode *s;
s=G.vertices[k].firstarc;
if(!s)
return -1;
while(s&&(v[s->adjvex]||s->adjvex==w))//不空,并且要么是访问过,要么是w,这样的点我们统统忽略
s=s->next;
if(s)//不空说明找到了
return s->adjvex;
else//否则-1
return -1;
}
void DFS(ALGraph G,int k)//对节点k进行深度优先遍历
{
int w;
v[k]=1;//进来就置1
cout<<G.vertices[k].data<<" ";//遍历输出
for(w=FirstAdjVex(G,k);w!=-1;w=NextAdjVex(G,k,w))//找到所有和k相邻的节点的编号,挨个深搜递归
if(!v[w])
DFS(G,w);
}
void DFSTraverse(ALGraph G)//对所有点进行深度优先遍历
{
int i;
memset(v,0,sizeof(v));
for(i=1;i<=G.vexnum;i++)
if(!v[i])
DFS(G,i);
}
void BFS(ALGraph G)//广度优先遍历
{
int i,k,w;
queue<int> q;//定义一个队列,存的是节点号,不是指针!
memset(v,0,sizeof(v));//因为之前深搜过,这里重新置0一下
for(i=1;i<=G.vexnum;i++)//依次对每个顶点进行考察
if(!v[i])//只要不空
{
v[i]=1;//只要不空,进来第一件事就是置1
cout<<G.vertices[i].data<<" ";//置1之后马上输出
q.push(G.vertices[i].data);//输出完了之后就入队
while(!q.empty())//只要队列不空
{
k=q.front();//取队首元素
q.pop();//然后队首出队
for(w=FirstAdjVex(G,k);w!=-1;w=NextAdjVex(G,k,w))//将所有和队首邻接的顶点依次入队,入一个,输出一个,别忘了还要置1哟~
if(!v[w])
{
v[w]=1;
cout<<G.vertices[w].data<<" ";
q.push(w);
}
}
}
}
int main()
{
ALGraph G;
Init(G);
cout<<"DFS:";
DFSTraverse(G);
cout<<endl;
cout<<"BFS:";
BFS(G);
}
