代码中所用到的结构体
typedef struct arcnode
{
int adjvex;//指向的下一个顶点
struct arcnode *next;//指向这个点的另一条边
}Arcnode,*pArcnode;
typedef struct vnode
{
pArcnode firstarc;//点所指向的第一条边
}Vnode,AdjList[30];
typedef struct graph
{
int Vnum,Arcnum;//点的数目,边的数目
AdjList vertice;
}Graph,*pGraph;
邻接表构造无向图
- 首先输入图的总边数和总点数,通过输入边的起始点和终点,来确立点和点之间的关系
- 注意点1:要申请两个新的指针p1,p2。p1从起始点指向终点,p2从终点指向起始点。以此通过两个有向的边构成一个无向的边。
- 注意点2:注意每个点的头指针为空和不为空的情况是不一样的。
void CreateGraph(pGraph G)//构造无向图
{
int i;
int node1,node2;//暂时存储数据
pArcnode p1,p2;//两个有向边组成一个无向边
printf("请输入无向图的总点数:\n");
scanf("%d",&G->Vnum);
getchar();
for(i=0;i<G->Vnum;i++)//给每个结点的第一个后继边初始化
{
G->vertice[i].firstarc=NULL;
}
printf("请输入无向图的总边数:\n");
scanf("%d",&G->Arcnum);
getchar();
printf("请输入点和点之间的连接:(例:1 5)\n");
for(i=0;i<G->Arcnum;i++)//循环输入边的信息
{
scanf("%d %d",&node1,&node2);
getchar();
p1=(pArcnode)malloc(sizeof(Arcnode));
p2=(pArcnode)malloc(sizeof(Arcnode));
p1->adjvex=node1;//构造连接,即两个有向边组成一个无向边
p1->next=NULL;
p2->adjvex=node2;
p2->next=NULL;
if(G->vertice[node1].firstarc==NULL&&G->vertice[node1].firstarc==NULL)//还未有邻接点时
{
G->vertice[node2].firstarc=p1;
G->vertice[node1].firstarc=p2;
}
else//已有邻接点时
{
p1->next=G->vertice[node2].firstarc;
G->vertice[node2].firstarc=p1;
p2->next=G->vertice[node1].firstarc;
G->vertice[node1].firstarc=p2;
}
}
}
DFS遍历无向图
- 这里主要用的的参数有:pos,遍历到的点;G,要遍历的图;visited【】,标记已经遍历的点。
- DFS是通过递归的方法遍历的
void DFSL(int pos,pGraph G,int visited[30])//从pos点开始,深度遍历无向图
{
pArcnode p;
printf("%d ",pos);//打印深度遍历的点
visited[pos]=1;//标记为以访问过
p=G->vertice[pos].firstarc;//将当前点的第一个指针赋值给p
while(p!=NULL)//是否存在邻接点
{
if(visited[p->adjvex]==0)//判断该邻接点是否被遍历过
{
DFSL(p->adjvex,G,visited);
}
p=p->next;//后移一位,为之后是否有邻接点做准备
}
}
BFS遍历无向图
- 这里主要用的的参数有:pos,遍历到的点;G,要遍历的图;visited【】,标记已经遍历的点;queue【】,一个数组作为队列来遍历数组。
- 通过将点pos存入队列,并将其标记,通过一个while循环对一个点的所连接的未被遍历的点进行遍历,遍历一个点所连接的点的方法为遍历该点所有的后继指针。
void BFSL(int pos,pGraph G,int visited[30])//从pos点开始进行广度优先遍历无向图
{
int queue[G->Vnum];//队列辅助BFS遍历
int head=0,tail=0;//队头、队尾指针
Arcnode* p;
queue[tail]=pos;
visited[pos]=1;//标记遍历过
tail++;
while(head!=tail)
{
pos=queue[head];//出队操作
head++;
printf("%d ",pos);
p=G->vertice[pos].firstarc;
while(p!=NULL)
{
if(visited[p->adjvex]==0)//判断是否遍历过
{
queue[tail]=p->adjvex;//入队操作
visited[p->adjvex]=1;//标记遍历过
tail++;
}
p=p->next;
}
}
}
源代码
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct arcnode
{
int adjvex;//指向的下一个顶点
struct arcnode *next;//指向这个点的另一条边
}Arcnode,*pArcnode;
typedef struct vnode
{
pArcnode firstarc;//点所指向的第一条边
}Vnode,AdjList[30];
typedef struct graph
{
int Vnum,Arcnum;//点的数目,边的数目
AdjList vertice;
}Graph,*pGraph;
void CreateGraph(pGraph G)//构造无向图
{
int i;
int node1,node2;//暂时存储数据
pArcnode p1,p2;//两个有向边组成一个无向边
printf("请输入无向图的总点数:\n");
scanf("%d",&G->Vnum);
getchar();
for(i=0;i<G->Vnum;i++)//给每个结点的第一个后继边初始化
{
G->vertice[i].firstarc=NULL;
}
printf("请输入无向图的总边数:\n");
scanf("%d",&G->Arcnum);
getchar();
printf("请输入点和点之间的连接:(例:1 5)\n");
for(i=0;i<G->Arcnum;i++)//循环输入边的信息
{
scanf("%d %d",&node1,&node2);
getchar();
p1=(pArcnode)malloc(sizeof(Arcnode));
p2=(pArcnode)malloc(sizeof(Arcnode));
p1->adjvex=node1;//构造连接,即两个有向边组成一个无向边
p1->next=NULL;
p2->adjvex=node2;
p2->next=NULL;
if(G->vertice[node1].firstarc==NULL&&G->vertice[node1].firstarc==NULL)//还未有邻接点时
{
G->vertice[node2].firstarc=p1;
G->vertice[node1].firstarc=p2;
}
else//已有邻接点时
{
p1->next=G->vertice[node2].firstarc;
G->vertice[node2].firstarc=p1;
p2->next=G->vertice[node1].firstarc;
G->vertice[node1].firstarc=p2;
}
}
}
void DFSL(int pos,pGraph G,int visited[30])//从pos点开始,深度遍历无向图
{
pArcnode p;
printf("%d ",pos);//打印深度遍历的点
visited[pos]=1;//标记为以访问过
p=G->vertice[pos].firstarc;//将当前点的第一个指针赋值给p
while(p!=NULL)//是否存在邻接点
{
if(visited[p->adjvex]==0)//判断该邻接点是否被遍历过
{
DFSL(p->adjvex,G,visited);
}
p=p->next;//后移一位,为之后是否有邻接点做准备
}
}
void BFSL(int pos,pGraph G,int visited[30])//从pos点开始进行广度优先遍历无向图
{
int queue[G->Vnum];//队列辅助BFS遍历
int head=0,tail=0;//队头、队尾指针
Arcnode* p;
queue[tail]=pos;
visited[pos]=1;//标记遍历过
tail++;
while(head!=tail)
{
pos=queue[head];//出队操作
head++;
printf("%d ",pos);
p=G->vertice[pos].firstarc;
while(p!=NULL)
{
if(visited[p->adjvex]==0)//判断是否遍历过
{
queue[tail]=p->adjvex;//入队操作
visited[p->adjvex]=1;//标记遍历过
tail++;
}
p=p->next;
}
}
}
int main()
{
pGraph G;
G=(pGraph)malloc(sizeof(Graph));
int i;
int visited[30]={0};
int pos;
CreateGraph(G);
printf("请输入DFS和BFS遍历的起始点:\n");
scanf("%d",&pos);
getchar();
if(pos<0||pos>G->Vnum)
{
assert(1);
}
printf("DFS遍历的结果:\n");
DFSL(pos,G,visited);
for(i=0;i<30;i++)
{
visited[i]=0;
}
printf("\n");
printf("BFS遍历的结果:\n");
BFSL(pos,G,visited);
return 0;
}
测试数据:
9
12
0 1
0 5
1 6
1 2
6 8
6 7
2 7
2 3
7 8
3 7
3 4
4 5
1
结果


本文介绍了如何使用邻接表构造无向图,并详细讲解了深度优先搜索(DFS)和广度优先搜索(BFS)遍历无向图的实现方法,包括递归遍历和队列遍历的过程。
——图之DFS和BFS遍历&spm=1001.2101.3001.5002&articleId=94474120&d=1&t=3&u=234260a705af40e389dce83d1c6a90a8)
4246

被折叠的 条评论
为什么被折叠?



