从给定图中任意指定的顶点(称为初始点)出发,按照某种搜索方法沿着图的边访问图中所有顶点,使每个顶点仅被访问一次,这个过程称为图的遍历
图的遍历方法有两种,一种叫深度优先遍历(DFS),另一种叫广度优先遍历(BFS).
图的邻接矩阵表示
通常图的表示有两种方法:邻接矩阵,邻接表。
两种方法各有各的好处。
没啥好说的直接上代码
邻接表
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
#define INIFINITY 65535
int visited[MAX]; //访问标志数组
/*邻接表结构*/
typedef char VertexType; //顶点类型
typedef int EdgeType; //权值类型
/*边表结点*/
typedef struct EdgeNode
{
int adjvex; //邻接点域,保存邻接点下标
struct EdgeNode *next; //链域,指向下一个邻接点
}EdgeNode;
typedef struct VertexNode
{
VertexType data; //顶点域
EdgeNode *firstedge; //边表头指针
}VertexNode,AdjList[MAX];
typedef struct
{
AdjList adjList;
int numVertexes,numEdges; //顶点数量和边数量
}GraphAdj;
/*邻接表创建*/
void create(GraphAdj &G)
{
int i,j,k;
EdgeNode *e;
printf("输入顶点数,边数:");
scanf("%d%d",&G.numVertexes,&G.numEdges);
getchar();
//printf("%d",G->numVertexes);
for(i=0;i<G.numVertexes;i++) //建立顶点表
{
printf("第(%d)个顶点: " ,i);
scanf("%c",&G.adjList[i].data);
getchar();
G.adjList[i].firstedge=NULL; //注意将边表置空
}
//printf("!");
for(k=0;k<G.numEdges;k++) //建立边表
{
printf("输入边(Vi,Vj)上的顶点序号:");
scanf("%d %d",&i,&j);
/*使用头插法加入边表结点*/
e=(EdgeNode *)malloc(sizeof(EdgeNode)); //生成边表结点
e->adjvex=j;
e->next=G.adjList[i].firstedge;
G.adjList[i].firstedge=e;
e=(EdgeNode *)malloc(sizeof(EdgeNode)); //生成边表结点
e->adjvex=i;
e->next=G.adjList[j].firstedge;
G.adjList[j].firstedge=e;
}
}
void DFS(GraphAdj G,int i){
EdgeNode *p;
visited[i]=1;
printf("%c",G.adjList[i].data);
p=G.adjList[i].firstedge;
while(p){
if(visited[p->adjvex]==0){
DFS(G,p->adjvex);
}
p=p->next;
}
}
void DFSTraverse(GraphAdj G){
for(int i;i<G.numVertexes;i++){
visited[i]=0;
}
for(int i=0;i<G.numVertexes;i++){
if(visited[i]==0){
DFS(G,i);
}
}
}
void BFS(GraphAdj G){
int queue[100];
int front=0,rear=-1,k;
for(int i=0;i<G.numVertexes;i++){
visited[i]=0;
}
for(int i=0;i<G.numVertexes;i++){
if(visited[i]==0){
visited[i]=1;
queue[++rear]=i;
printf("%c", G.adjList[i].data);
while(rear>=front){
k=queue[front++];
EdgeNode *e=G.adjList[k].firstedge;
while(e){
if(visited[e->adjvex]==0){
visited[e->adjvex]=1;
printf("%c", G.adjList[e->adjvex].data);
queue[++rear]=e->adjvex;
}
e=e->next;
}
}
}
}
}
int main(){
GraphAdj G;
create(G);
printf("深度优先遍历为:");
DFSTraverse(G);
printf("\n");
printf("广度优先遍历为:");
BFS(G);
printf("\n图遍历完毕");
return 0;
}
运行结果
邻接矩阵
#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100 //最大定点顶点数
#define MAX 100
int visited[MAX];
typedef int EdgeType;
typedef char VertexType; //顶点类型
typedef struct{
VertexType vexs[MAXVEX]; //顶点表
EdgeType arc[MAXVEX][MAXVEX]; //邻接矩阵,可看作边表
int vexnum,arcnum; //图中当前的顶点数与边数
}MGraph;
void create(MGraph &G)
{
int i,j,k;
printf("输入顶点数和边数:");
scanf("%d%d",&G.vexnum,&G.arcnum); //输入顶点数和边数
getchar();
for(i=0;i<G.vexnum;i++)
{
printf("第(%d)个顶点: ",i);
scanf("%c",&G.vexs[i]);
getchar();
}
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
G.arc[i][j]=0 ; //邻接矩阵初始化
for(k=0;k<G.arcnum;k++)
{
printf("输入边(vi,vj)上的上标i:");
scanf("%d %d",&i,&j); //输入边(vi,vj)上的权W
G.arc[i][j]=1;
G.arc[j][i]=G.arc[i][j]; //因为是无向图,矩阵对称
}
}
//邻接矩阵的深度优先递归算法
void DFS (MGraph G,int i)
{
int j;
visited[i]=1; //标记为访问过
printf("%c",G.vexs[i]);
for(j=0;j<G.vexnum;j++){
if(G.arc[i][j]==1&&visited[j]==0)
DFS(G,j);
}
}
//邻接矩阵的深度遍历操作
void DFSTraverse(MGraph G)
{
int i;
for(i=0;i<G.vexnum;i++)visited[i]=0;
for(i=0;i<G.vexnum;i++)
if(visited[i]==0)
DFS(G,i);
}
void BFS(MGraph G)
{
int i,j,front=0,rear=-1,queue[100],k;
for(i=0;i<G.vexnum;i++)visited[i]=0;
for(i=0;i<G.vexnum;i++){
if(visited[i]==0){
printf("%c",G.vexs[i]);
visited[i]=1;
queue[++rear]=i;
while(rear>=front){
k=queue[front++];
for(j=0;j<G.vexnum;j++){
if(G.arc[k][j]==1&&visited[j]==0){
printf("%c",G.vexs[j]);
visited[j]=1;
queue[++rear]=j;
}
}
}
}
}
}
int main()
{
MGraph G;
create(G);
printf("深度优先遍历为:\n");
DFSTraverse(G);
printf("\n");
printf("广度度优先遍历为:\n");
BFS(G);
printf("\n图遍历完毕");
return 0;
}
运行结果
为防止有人看不懂图构建成什么样给你们画个图吧(很丑)
然后,这里写的是无向图,有向图其实差不多,创建图的地方少一些代码而已,这里也没有设置权值,需要的话也就是结构体里加一点还有邻接矩阵表示法弄个无穷大的区别。。。。