算法——图的遍历

前言:图的遍历是指对图的所有顶点按一定的顺序进行访问,遍历方法一般有两种,深度优先搜索(DFS)和广度优先搜( BFS)。

一、深度优先搜索(DFS)遍历图

1.DFS遍历图

      深度优先显然是以深度作为关键词进行遍历,每次都是沿着路径到不能再前进时才回退到最近的岔路口 ,就像走迷宫一样,一直沿着一条路走,直到碰到走不通的通道然后回到上一个最近的路口。

2.用邻接矩阵实现DFS遍历图

不明白邻接矩阵存储图的可以去看上一篇博客。

#define maxv 1000

int n,G[maxv][maxv];
bool vis[maxv]={false};

void DFS(int visit)
{
    vis[visit]=true;//设置visit顶点已经被访问标志
    for(int v=0;v<n;v++)//访问与点visit相连的全部顶点
    {
        if(vis[v]==false&&G[visit][v]!=inf)//若v未被访问且visit可以到达v
            DFS(v);//要说明的一点是DFS()里面的参数不固定,可以根据题目需要添加参数,例如每
                        连通块中含有的顶点个数等。
    }
}


void DFSTrave()//遍历整个图
{
    for(int i=0;i<n;i++)//对于图的每一个顶点
    {
        if(vis[i]==false)//如果顶点i未被访问
            DFS(i);//调用dfs访问i所在的连通块,不懂什么是连通块的可以先百度一下联通分量和强
                        联通分量的概念
    }
    
}

3.用邻接表实现DFS遍历图

vector<int> adj[maxv];
int n;
bool vis[maxv]={false};

void DFS(int visit)
{
    vis[visit]=true;
    //如果要对visit进行一些操作可以在此处进行
    for(int j=0;j<adj[visit].size();j++)//根据邻接表的特点访问与顶点visit相连接的所有顶点
                                            与邻接矩阵的访问不相同的地方就在于此,可以对比
                                               邻接矩阵进行理解记忆
    {    
        int v=adj[visit][j];
        if(vis[v]==false)
            DFS(v);
    }
}

void Trave()
{
    for(int u=0;u<n;u++)
    {
        if(vis[u]==false)
            DFS(u);
    }
}

二、广度优先搜索(BFS)遍历图

1.BFS遍历图 

      与dfs不同的是使用bfs遍历图的时候需要使用一个队列,通过反复取出队首顶点,将该顶点可到达的未曾加入过队列的顶点(不是未曾访问过的顶点)全部入队,直到队列为空时遍历结束。

2.邻接矩阵实现BFS

//可对比dfs的邻接矩阵实现方法和下面的bfs的邻接表实现方法,此处不再做详细讲解


int n,G[maxv][maxv];
bool vis[maxv]={false};

void BFS(int visit)
{
    queue<int> q;
    q.push(visit);
    vis[visit]=true;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int v=0;v<n;v++)
        {
            if(vis[v]==false&&G[u][v]!=INF)
            {
                q.push(v);
                vis[v]=true;
            }
        }
    }
}

void Trave()
{
    for(int i=0;i<n;i++)
    {
        if(vis[i]==false)
            BFS(i);
    }
}

3.邻接表实现BFS

#define maxv 1000
vector<int> vec[maxv];
int vis[maxv];

void BFS(int visit)
{
    queue<int> q;//定义一个队列

    q.push(visit);//当前定点入队
    vis[visit]=1;//进行标记
    while(!q.empty())//如果对列为空则访问此连通块结束
    {
       int u=q.front();//取出队首元素
        q.pop();//将队首顶点出队
        for(int v=0;v<vec[u].size();v++)//访问u能到达的每一个顶点
        {
            int j=vec[u][v];
            if(vis[j]==0)//如果没有入过队列,就将其加入到队列当中
            {
                vis[j]=1;
                q.push(j);

            }
        }

    }
}

void Trave()//遍历图的每一个顶点,和dfs类似
{
    for(int i=0;i<n;i++)
    {
        if(vis(i)==false)
            BFS(i);    
    }
}

 


更完~~~~~~~~~~~~~

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
2. 系统设计 1.用到的抽象数据类型的定义 的抽象数据类型定义: ADT Graph{ 数据对象V:V是具有相同特性的数据元素的集合,称为顶点集 数据关系R: R={VR} VR={<v,w>|v,w∈V且P(v,w),<v,w>表示从v到w的弧, 谓词P(v,w)定义了弧<v,w>的意义或信息} 基本操作P: CreatGraph(&G,V,VR) 初始条件:V是的顶点集,VR是中弧的集合 操作结果:按V和VR的定义构造G DestroyGraph(&G) 初始条件:G存在 操作结果:销毁G InsertVex(&G,v) 初始条件:G存在,v和中顶点有相同特征 操作结果:在G中增添新顶点v …… InsertArc(&G,v,w) 初始条件:G存在,v和w是G中两个顶点 操作结果:在G中增添弧<v,w>,若G是无向的则还增添对称弧<w,v> …… DFSTraverse(G,Visit()) 初始条件:G存在,Visit是顶点的应用函数 操作结果:对进行深度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。一旦Visit()失败,则操作失败 BFSTraverse(G,Visit()) 初始条件:G存在,Visit是顶点的应用函数 操作结果:对进行广度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。一旦Visit()失败,则操作失败 }ADT Graph 栈的抽象数据类型定义: ADT Stack{ 数据对象:D={ai|ai∈ElemSet,i=1,2,…,n,n≥0} 数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,…,n} 约定an端为栈顶,ai端为栈底 基本操作: InitStack(&S) 操作结果:构造一个空栈S DestroyStack(&S) 初始条件:栈S已存在 操作结果:将S清为空栈 StackEmpty(S) 初始条件:栈S已存在 操作结果:若栈S为空栈,则返回TRUE,否则FALSE …… Push(&S,e) 初始条件:栈S已存在 操作结果:插入元素e为新的栈顶元素 Pop(&S,&e) 初始条件:栈S已存在且非空 操作结果:删除S的栈顶元素,并用e返回其值 StackTraverse(S,visit()) 初始条件:栈S已存在且非空 操作结果:从栈底到栈顶依次对S的每个数据元素调用函数visit(),一旦visit()失败,则操作失效 }ADT Stack 队列的抽象数据类型定义: ADT Queue{ 数据对象:D={ai|ai∈ElemSet,i=1,2,…,n,n≥0} 数据关系:Rl={<ai-1,ai>|ai-1,ai∈D,i=2,…,n} 约定其中ai端为队列头,an端为队列尾。 基本操作: InitQueue(&Q) 操作结果:构造一个空队列Q DestroyQueue(&Q) 初始条件:队列Q已存在 操作结果:队列Q被销毁,不再存在 QueueEmpty(Q) 初始条件:队列Q已存在 操作结果:若Q为空队列,则返回TRUE,否则FALSE …… EnQueue(&Q,e) 初始条件:队列Q已存在 操作结果:插入元素e为Q的新的队尾元素 DeQueue(&Q,&e) 初始条件:Q为非空队列 操作结果:删除Q的队头元素,并用e返回其值 }ADT Queue 2.主程序的流程: 调用CreateDN函数创建的邻接表G; 调用PrintDN函数输出邻接表G; 调用DFSTraverse函数深度优先遍历; 调用BFSTraverse函数广度优先遍历
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.无名之辈

1毛也是爱~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值