众所周知,图有经典的两种遍历方式:深度优先遍历和广度优先遍历
首先我们就来说说深度优先遍历,其他的不说了,直接上代码,分为递归个非递归的方式啊
首先是递归的方式实现的,比较简单,考虑到存储结构由邻接矩阵和邻接表,有分为两种:一种是邻接矩阵存储的递归,简单点说就是用数组来存储;另一种是邻接表存储的,也就是说用链表的方式存储的
一、递归
1、邻接矩阵:
#include<stdio.h>
#define MAX 100
typedef struct
{
int e[MAX][MAX];
int ves;
int edge;
int book[MAX];//标志判断是否有被访问过
}MGraph;
void createMGraph(MGraph *G)
{
int i;
int j;
int start;
int end;
printf("please input the ves and edge:\n");
scanf("%d %d",&G->ves,&G->edge);
//初始化
for(i = 0; i < G->ves; i++)
{
for(j = 0; j < G->ves; j++)
{
G->e[i][j] = 0;
}
G->book[i] = 0;//没被访问过的结点置为0
}
//创建邻接矩阵
printf("please input the (vi,vj)\n");
for(i = 0; i < G->edge; i++)
{
scanf("%d %d",&start,&end);
G->e[start][end] = 1;
}
}
void dfs(MGraph *G,int ves)
{
int i;
G->book[ves] = 1;//被访问过的结点置为1
printf("%d ",ves);
for(i = 0; i < G->ves; i++)
{
if(G->e[ves][i] != 0 && G->book[i] == 0)
{
dfs(G,i);
}
}
}
int main()
{
MGraph G;
createMGraph(&G);
dfs(&G,0);
return 0;
}
2、邻接表:
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct// 边表结点
{
int adjves;//存储顶点的下标
struct EdgeNOde* next;//连接下一个邻点
}EdgeNode;
typedef struct VertexNode//顶点表结点
{
int ves;//顶点的值
EdgeNode* firstedge;//相连的顶点的值
}VertexNode,AdjList[MAX];
//邻接表
typedef struct
{
AdjList adjlist;
int ves;//顶点
int edge;//边
int book[MAX];//判断是否有被访问过
}MGraph;
void createMGraph(MGraph *G)
{
int i;
int start;
int end;
EdgeNode *e;
printf("please input the ves and edge:\n");
scanf("%d%d",&(G->ves),&(G->edge));
//初始化
printf("please input the ves:\n");
for(i = 0; i < G->ves; i++)//输入顶点
{
scanf("%d",&(G->adjlist[i].ves));
G->adjlist[i].firstedge = NULL;
}
//创建邻接矩阵
printf("please input the edges:\n");
for(i = 0; i < G->edge; i++)
{
scanf("%d%d",&start,&end);
e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
e->adjves = end;
e->next = G->adjlist[start].firstedge;
G->adjlist[start].firstedge = e;//类似于链表的前插
e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
e->adjves = start;
e->next = G->adjlist[end].firstedge;
G->adjlist[end].firstedge = e;//类似于链表的前插
}
}
void dfs(MGraph *G,int ves)
{
EdgeNode *p;
G->book[ves] = 1;//被访问过的结点置为1
printf("%d ",G->adjlist[ves].ves);
p = G->adjlist[ves].firstedge;//取顶点
while(p)
{
if(G->book[p->adjves] == 0)//未被访问过
{
dfs(G,p->adjves);
}
p = p->next;
}
}
int main()
{
MGraph G;
createMGraph(&G);
dfs(&G,0);
return 0;
}
结果:
二、非递归:
1、邻接矩阵:
主要的思想方法:
基本的思想是:
初始化栈
输出起始的顶点,起始顶点改为“已访问”的标志,将起始顶点进栈
重复一下的操作直至栈为空:
取栈顶元素顶点,存在着未被访问的邻结点W
输出顶点W,将顶点W改为“已访问”,将W进栈;
否则,当前顶点退栈
#include<iostream>
#include<stack>
#define MAX 100
using namespace std;
typedef struct
{
int e[MAX][MAX];
int edge;//边
int ves;//顶点
int book[MAX];//判断标志是否是被访问
}MGraph;
void createMGraph(MGraph* G)
{
int i;
int j;
int start;
int end;
cout<<"please input the ves and edge:"<<endl;
cin>>G->ves>>G->edge;
//初始化
for(i = 0; i < G->ves; i++)
{
for(j = 0; j < G->ves; j++)
{
G->e[i][j] = 0;
}
G->book[i] = 0;//标识全部置0,表示没有访问过结点
}
//创建邻接矩阵
cout<<"please input the edge(vi,vj)\n"<<endl;
for(i = 0; i < G->edge; i++)
{
cin>>start>>end;
G->e[start][end] = 1;
}
}
void dfs(MGraph* G,int ves)
{
stack<int> s;//创建一个栈
cout<<ves;
G->book[ves] = 1;//已经访问过结点ves了
s.push(ves);//入栈
while(!s.empty())
{
int data;
int i;
data =s.top();//取top的顶点
for(i = 0; i < G->ves; i++)
{
if(G->e[data][i] != 0 && G->book[i] != 1)
{
cout<<i ;//访问
G->book[i] = 1;
s.push(i);
break;
}
}
if(i == G->ves)//data相邻的结点都访问结束了,就弹出data
{
s.pop();
}
}
}
int main()
{
MGraph G;
createMGraph(&G);
dfs(&G,0);
return 0;
}
2、邻接表
思路过程跟邻接矩阵一样的
#include<iostream>
#include<stdlib.h>
#include<stack>
#include<stdio.h>
#define MAX 100
using namespace std;
struct Node// 边表结点
{
int adjves;//存储顶点的下标
struct Node* next;//连接下一个邻点
};
typedef struct Node EdgeNode;
typedef struct VertexNode//顶点表结点
{
int ves;//顶点的值
EdgeNode* firstedge;//相连的顶点的值
}VertexNode,AdjList[MAX];
typedef struct
{
AdjList adjlist;//邻接表
int ves;//顶点
int edge;//边
int book[MAX];//判断是否有被访问过
}MGraph;
void createMGraph(MGraph *G)
{
int i;
int start;
int end;
EdgeNode *e;
cout<<"please input the ves and edge:"<<endl;
cin>>G->ves>>G->edge;
//初始化
cout<<"please input the ves:"<<endl;
for(i = 0; i < G->ves; i++)//输入顶点
{
cin>>G->adjlist[i].ves;
G->adjlist[i].firstedge = NULL;
}
//创建邻接矩阵
cout<<"please input the edges:"<<endl;;
for(i = 0; i < G->edge; i++)
{
cin>>start>>end;
e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
e->adjves = end;
e->next = G->adjlist[start].firstedge;
G->adjlist[start].firstedge = e;//类似于链表的前插
e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
e->adjves = start;
e->next = G->adjlist[end].firstedge;
G->adjlist[end].firstedge = e;//类似于链表的前插
}
}
void dfs(MGraph *G,int i)
{
stack <int>s;
EdgeNode *p;
memset(G->book,0,sizeof(G->book));//清空标志位
G->book[i]=1;
s.push(i);
cout<<G->adjlist[i].ves;
p = G->adjlist[i].firstedge;
while(!s.empty())
{
p = G->adjlist[s.top()].firstedge;
while(p)
{
if(G->book[p->adjves] == 0)
{
G->book[p->adjves]=1;
printf("%d",G->adjlist[p->adjves].ves);
s.push(p->adjves);
p = G->adjlist[p->adjves].firstedge;
}
else
p=p->next;
}
if(p == NULL)
{
s.pop();
}
}
}
int main()
{
MGraph G;
createMGraph(&G);
dfs(&G,0);
return 0;
}
结果: