深度优先遍历:优先去更深更远的地方,用递归实现
类似走迷宫,选择一条路走到死路再往回走,走回上一条路口再选择其它的路
如果A的邻接点是BCD,B的邻接点是E,D的邻接点是FG
那么深度优先遍历是:A-BE-C-DFG
广度优先遍历:优先去更广的地方,用队列实现
如果A的邻接点是BCD,B的邻接点是E,D的邻接点是FG
那么广度优先遍历是:A-BCD-E-FG
1.邻接矩阵:O(n²)
#include <iostream>
using namespace std;
int visited[10];
class MGraph{
public:
MGraph(char a[],int n,int e);
~MGraph(){}
void DFS(int v);
void BFS(int v);
private:
char vertex[10];//存放顶点
int edge[10][10];//存放边
int vertexNum,edgeNum;//顶点数,边数
};
MGraph::MGraph(char a[],int n,int e){
int i,j,k;
vertexNum=n;
edgeNum=e;
for(i=0;i<vertexNum;i++)
vertex[i]=a[i];
for(i=0;i<vertexNum;i++)
for(j=0;j<vertexNum;j++)
edge[i][j]=0;//初始化邻接矩阵为全0
for(k=0;k<edgeNum;k++){//存储每一条边
cin>>i>>j;
edge[i][j]=1;
edge[j][i]=1;//无向图
}
}
void MGraph::DFS(int v){
int i;
cout<<vertex[v];
visited[v]=1;
for(i=0;i<vertexNum;i++){
if(edge[v][i]==1&&visited[i]==0)//找编号v的所有未被访问的邻接点
DFS(i);
}
}
void MGraph::BFS(int v){
int w,j,Q[10];
int front=-1;
int rear=-1;
cout<<vertex[v];
visited[v]=1;
Q[++rear]=v;//入队
while(front!=rear){//队列非空
w=Q[++front];//队头元素出队
for(j=0;j<vertexNum;j++){
if(edge[w][j]==1&&visited[j]==0){//扫描编号w那一行,找w的邻接点
cout<<vertex[j];
visited[j]=1;
Q[++rear]=j;
}
}
}
}
int main()
{
int i;
char ch[5]={'A','B','C','D','E'};
MGraph mg(ch,5,4);
for(i=0;i<10;i++)
visited[i]=0;
cout<<"深度优先遍历:";
mg.DFS(0);
cout<<endl;
for(i=0;i<10;i++)
visited[i]=0;
cout<<"广度优先遍历:";
mg.BFS(0);
return 0;
}
运行结果
0 1
0 3
0 2
3 4
深度优先遍历:ABCDE
广度优先遍历:ABCDE
2.邻接表:树的孩子表示法,O(n+e)
边表(邻接表):顶点 v 的所有邻接点链成的单链表
顶点表:所有边表的头指针和存储顶点信息的一维数组
#include <iostream>
using namespace std;
int visited[10];
struct EdgeNode{//边表顶点
int adjvex;//邻接点域
EdgeNode *next;
};
struct VertexNode{
char vertex;
EdgeNode *firstEdge;
};
class ALGraph{
public:
ALGraph(char a[],int n,int e);
~ALGraph();
void DFS(int v);
void BFS(int v);
private:
VertexNode adjlist[10];//存放顶点表的数组
int vertexNum,edgeNum;
};
ALGraph::ALGraph(char a[],int n,int e){
int i,j,k;
EdgeNode *s=NULL;
vertexNum=n;
edgeNum=e;
for(i=0;i<vertexNum;i++){//初始化顶点表
adjlist[i].vertex=a[i];
adjlist[i].firstEdge=NULL;
}
for(k=0;k<edgeNum;k++){
cout<<"请输入边的两个顶点:";
cin>>i>>j;
s=new EdgeNode;
s->adjvex=j;
s->next=adjlist[i].firstEdge;//将结点s插入表头
adjlist[i].firstEdge=s;
}
}
ALGraph::~ALGraph(){
EdgeNode *p,*q;
p=q=NULL;
for(int i=0;i<vertexNum;i++){
p=q=adjlist[i].firstEdge;
while(p!=NULL){
p=p->next;
delete q;
q=p;
}
}
}
void ALGraph::DFS(int v){
int j;
EdgeNode *p=NULL;
cout<<adjlist[v].vertex;
visited[v]=1;
p=adjlist[v].firstEdge;//p指向顶点v的边表
while(p!=NULL){
j=p->adjvex;//v邻接点的编号
if(visited[j]==0)
DFS(j);
p=p->next;
}
}
void ALGraph::BFS(int v){
int w,j,Q[10],front=-1,rear=-1;
EdgeNode *p=NULL;
cout<<adjlist[v].vertex;
visited[v]=1;
Q[++rear]=v;//入队
while(front!=rear){
w=Q[++front];//队头元素w出队
p=adjlist[w].firstEdge;//找w所有邻接点:p指向w的边表
while(p!=NULL){
j=p->adjvex;//记下邻接点的编号
if(visited[j]==0){
Q[++rear]=j;//入队
cout<<adjlist[j].vertex;
visited[j]=1;
}
p=p->next;
}
}
}
int main()
{
char ch[5]={'A','B','C','D','E'};
int i;
ALGraph alg(ch,5,5);
for(i=0;i<10;i++)
visited[i]=0;
cout<<"深度优先遍历:";
alg.DFS(0);
cout<<endl;
for(i=0;i<10;i++)//重新初始化visited[]数组
visited[i]=0;
cout<<"广度优先遍历:";
alg.BFS(0);
return 0;
}
运行结果
请输入边的两个顶点:0 1
请输入边的两个顶点:0 4
请输入边的两个顶点:1 2
请输入边的两个顶点:2 3
请输入边的两个顶点:4 3
深度优先遍历:AEDBC
广度优先遍历:AEBDC