深度优先遍历与广度优先遍历

这篇博客介绍了图的深度优先遍历(DFS)和广度优先遍历(BFS)的基本概念,并通过C++代码展示了这两种遍历方法的实现。在DFS中,算法沿着路径深入直到找到死路再回溯,而在BFS中,算法首先遍历更广的区域。文中提供了邻接矩阵和邻接表两种数据结构的实现方式,分别用于存储图的连接信息。通过实例展示了不同遍历顺序的结果。
摘要由CSDN通过智能技术生成

深度优先遍历:优先去更深更远的地方,用递归实现

类似走迷宫,选择一条路走到死路再往回走,走回上一条路口再选择其它的路

如果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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值