/图的深度优先搜索遍历——DFS/
采用邻接矩阵,时间复杂度为n*^2。如果采用邻接表存储,DFS的时间复杂度会变成n+e。
在BFS中我会采用邻接表的存储方法。
本程序的输入输出:
样例输入
6
0 0 0 1 0 0
0 0 1 1 0 0
0 1 0 1 0 0
1 1 1 0 0 0
0 0 0 0 0 1
0 0 0 0 1 0
样例输出
0 3 1 2 4 5
#include<stdio.h>
#define max 50
#define maxcost 10000
typedef int elemtype;
typedef struct
{
int vertexnum;//顶点个数
elemtype graph[max][max];//邻接矩阵
}graph;
void DFS(graph G,int i,int depth,bool vis[])
{
int t;
vis[i]=true;
printf("%d ",i);
for(t=0;t<G.vertexnum;t++)
if(vis[t]==false&&G.graph[i][t]!=maxcost)
DFS(G,t,depth+1,vis);
}
void DFStraverse(graph G,bool vis[])
{
int i;
for(i=0;i<G.vertexnum;i++)
{
if(vis[i]==false)
DFS(G,i,1,vis);
}
}
int main()
{
graph G;
scanf("%d",&G.vertexnum);
int i,j;
for(i=0;i<G.vertexnum;i++)
for(j=0;j<G.vertexnum;j++)
{
scanf("%d",&G.graph[i][j]);
if(G.graph[i][j]==0&&i!=j)
G.graph[i][j]=maxcost;
}
bool vis[G.vertexnum]={false};
DFStraverse(G,vis);
return 0;
}
/树的广度优先搜索遍历——BFS/
样例输入:
5 8
1 0
0 2
2 4
4 3
3 1
1 2
0 3
3 4
样例输出:
0 2 3 4 1
#include<stdio.h>
#include<malloc.h>
#define maxnum 100
#define error 1
#define ok 0
typedef int elem;
typedef int status;
typedef int vextype;
typedef int edgetype;
typedef int weightype;
typedef struct arcnode
{
int adjvex;//该弧指向的顶点
struct arcnode *nextarc;//指向下一条弧的指针
weightype weight;//权值
}arcnode;//表结点
typedef struct vnode
{
vextype data;//顶点信息
arcnode *firstarc;//指向下一条弧的指针
}vnode,list[maxnum];//头结点
typedef struct
{
list vertices;
int vernum,arcnum;
}graph;
typedef struct qnode
{
elem data;//队列元素
struct qnode *next;//指向下一个元素的指针
}qnode,*queueptr;//链式队列的结构
typedef struct
{
queueptr front;//队列的头
queueptr rear;//队列的尾
}linkqueue;//还可以不放在结构体里,单独拿出来
status linkqueue_init(linkqueue &q)
{
q.front=q.rear=(queueptr)malloc(sizeof(qnode));
q.rear->next=NULL;
return ok;
}//初始化一个队列
status linkqueue_push(linkqueue &q,elem e)
{
q.rear->data=e;
queueptr s;
s=(queueptr)malloc(sizeof(qnode));
q.rear->next=s;
q.rear=s;
q.rear->next=NULL;
return ok;
}//进队一个元素
status linkqueue_pop(linkqueue &q)
{
queueptr t;
t=q.front->next;
q.front=t;
return ok;
}//出队一个元素
elem linkqueue_getfront(linkqueue &q)
{
return q.front->data;
}//取队头元素
status linkqueue_empty(linkqueue &q)
{
if(q.front==q.rear)
return ok;
else
return error;
}//判断队列是否为空
int LocateVer(graph &G,int u)
{
int i;
for(i=0;i<G.vernum;i++)
if(u==G.vertices[i].data)
return i;
}
void CreateG(graph &G)
{
int i,j,k;
scanf("%d%d", &G.vernum,&G.arcnum);
for(i=0;i<G.vernum;i++)
{
G.vertices[i].data=i;
G.vertices[i].firstarc=NULL;
}//初始化顶点
int v1,v2,w;
for(k=0;k<G.arcnum;k++)
{
scanf("%d%d",&v1,&v2);//输入顶点和权值
i=LocateVer(G,v1);
j=LocateVer(G,v2);
arcnode *p1,*p2;
p1=(arcnode*)malloc(sizeof(arcnode));
p1->adjvex=j;//赋值给p->adjvex指向的顶点域
//p1->weight=w;//边表结点的权值
p1->nextarc=G.vertices[i].firstarc;//它的nextarc指针域指向i结点的firstarc指针域
G.vertices[i].firstarc=p1;
p2=(arcnode*)malloc(sizeof(arcnode));
p2->adjvex=i;
//p2->weight=w;
p2->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=p1;//将点i的第一条指针指向
}
}
/*采用邻接表表示图的广度优先遍历*/
void BFS(graph &G)
{
printf("0 ");
int u,w,v;
arcnode *p;
linkqueue q;
linkqueue_init(q);
int visited[G.arcnum]={0};
visited[0]=1; //顶点v0已被访问
linkqueue_push(q,0); //将顶点v0入队
while(linkqueue_empty(q)==error)
{
u=linkqueue_getfront(q);
linkqueue_pop(q);//将顶点元素u出队,开始访问u的所有邻接点
v=LocateVer(G,u);//得到顶点u的对应下标
for(p=G.vertices[v].firstarc;p;p=p->nextarc) //遍历顶点u的邻接点
{
w=p->adjvex;
if(visited[w]==0) //顶点p未被访问
{
printf("%d ",G.vertices[w].data); //打印顶点p
visited[w]=1; //顶点p已被访问
linkqueue_push(q,G.vertices[w].data); //将顶点p入队
}
}
}
}
int main()
{
graph G;
CreateG(G);
BFS(G);
return 0;
}