dfs与dfs遍历图节点

目录

一、图的存储

1.1 邻接矩阵

1.2 邻接表

3.两者区别

二、图的深度遍历(dfs)和广度遍历(bfs)---邻接矩阵存储

2.1 图的深度遍历(dfs)

2.2 图的广度遍历(bfs)


一、图的存储

图的存储结构主要分两种,一种是邻接矩阵,一种是邻接表。

1.1 邻接矩阵

图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。
设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:
这里写图片描述
看一个实例,下图左就是一个无向图。
这里写图片描述
从上面可以看出,无向图的边数组是一个对称矩阵。所谓对称矩阵就是n阶矩阵的元满足aij = aji。即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的。
从上面可以看出,无向图的边数组是一个对称矩阵。所谓对称矩阵就是n阶矩阵的元满足aij = aji。即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的。
从这个矩阵中,很容易知道图中的信息。
(1)要判断任意两顶点是否有边无边就很容易了;
(2)要知道某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
(3)求顶点vi的所有邻接点就是将矩阵中第i行元素扫描一遍,arc[i][j]为1就是邻接点;
而有向图讲究入度和出度,顶点vi的入度为1,正好是第i列各数之和。顶点vi的出度为2,即第i行的各数之和。
若图G是网图,有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:这里写图片描述

1.2 邻接表

邻接矩阵是不错的一种图存储结构,但是,对于边数相对顶点较少的图,这种结构存在对存储空间的极大浪费。因此,找到一种数组与链表相结合的存储方法称为邻接表。
邻接表的处理方法是这样的:
(1)图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过,数组可以较容易的读取顶点的信息,更加方便。
(2)图中每个顶点vi的所有邻接点构成一个线性表,由于邻接点的个数不定,所以,用单链表存储,无向图称为顶点vi的边表,有向图则称为顶点vi作为弧尾的出边表。
例如,下图就是一个无向图的邻接表的结构。
这里写图片描述
从图中可以看出,顶点表的各个结点由data和firstedge两个域表示,data是数据域,存储顶点的信息,firstedge是指针域,指向边表的第一个结点,即此顶点的第一个邻接点。边表结点由adjvex和next两个域组成。adjvex是邻接点域,存储某顶点的邻接点在顶点表中的下标,next则存储指向边表中下一个结点的指针。
对于带权值的网图,可以在边表结点定义中再增加一个weight的数据域,存储权值信息即可。如下图所示。
这里写图片描述

3.两者区别

对于一个具有n个顶点e条边的无向图
它的邻接表表示有n个顶点表结点2e个边表结点
对于一个具有n个顶点e条边的有向图
它的邻接表表示有n个顶点表结点e个边表结点
如果图中边的数目远远小于n2称作稀疏图,这是用邻接表表示比用邻接矩阵表示节省空间;
如果图中边的数目接近于n2,对于无向图接近于n*(n-1)称作稠密图,考虑到邻接表中要附加链域,采用邻接矩阵表示法为宜。

二、图的深度遍历(dfs)和广度遍历(bfs)---邻接矩阵存储

输入矩阵:

0 1 0 0 0 0 0 1 0 0
1 0 1 1 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 1 1 1 0 0 0
0 0 0 1 0 1 0 0 0 0
0 0 0 1 1 0 1 0 0 0
0 0 0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 1 1 0

2.1 图的深度遍历(dfs)

1、从顶点v出发深度遍历图G的算法:① 访问v, ② 依次从顶点v未被访问的邻接点出发深度遍历。
2、一点心得:dfs算法最大特色就在于其递归特性,使得算法代码简洁。

2.2 图的广度遍历(bfs)

1、从顶点v出发遍历图G的算法:
①访问v,②假设最近一层的访问顶点依次为vi1,vi2,vi3...vik,则依次访问vi1,vi2,vi3...vik的未被访问的邻接点
③重复②知道没有未被访问的邻接点为止

2、一点心得:bfs算法其实就是一种层次遍历算法。从算法描述可以看到该算法要用到队列这一数据结构。这里用STL中的<queue>实现。

#include<iostream>
using namespace std;
 
int a[11][11];
bool visited[11];
 
void store_graph()  //邻接矩阵存储图
{
    int i,j;
 
    for(i=1;i<=10;i++)
        for(j=1;j<=10;j++)
            cin>>a[i][j];
}
 
void dfs_graph()    //深度遍历图
{
    void dfs(int v);//dfs在该方法下面,所以需要定义
 
    memset(visited,false,sizeof(visited));
 
    for(int i=1;i<=10;i++)  //遍历每个顶点是为了防止图不连通时无法访问每个顶点
        if(visited[i]==false)
            dfs(i);
}
 
void dfs(int v)  //深度遍历顶点
{
    int Adj(int x);//Adj在该方法下面,所以需要定义
 
    cout<<v<<" ";  //访问顶点v
    visited[v]=true;
 
    int adj=Adj(v);
    while(adj!=0)
    {
        if(visited[adj]==false)   
            dfs(adj);      //递归调用是实现深度遍历的关键所在
 
        adj=Adj(v);
    }
}
 
int Adj(int x)   //求邻接点
{
    for(int i=1;i<=10;i++)
        if(a[x][i]==1 && visited[i]==false)
            return i;
 
    return 0;
}
 
int main()
{
    cout<<"初始化图:"<<endl;
    store_graph();
 
    cout<<"dfs遍历结果:"<<endl;
    dfs_graph();
 
    return 0;
}
#include<iostream>
#include<queue>    
using namespace std;
 
int a[11][11];
bool visited[11];
 
void store_graph()  
{
    for(int i=1;i<=10;i++)
        for(int j=1;j<=10;j++)
            cin>>a[i][j];
}
 
void bfs_graph()    
{
    void bfs(int v);
 
    memset(visited,false,sizeof(visited));
 
    for(int i=1;i<=10;i++)  
        if(visited[i]==false)
            bfs(i);
}
 
void bfs(int v)
{
    int Adj(int x);
 
    queue<int> myqueue;
    int adj,temp;
 
    cout<<v<<" ";
    visited[v]=true;
    myqueue.push(v);
 
    while(!myqueue.empty())    //队列非空表示还有顶点未遍历到
    {
        temp=myqueue.front();  //获得队列头元素
        myqueue.pop();         //头元素出对
 
        adj=Adj(temp);
        while(adj!=0)
        {
            if(visited[adj]==false)
            {
                cout<<adj<<" ";
                visited[adj]=true;
                myqueue.push(adj);   //进对
            }
 
            adj=Adj(temp);
        }
    }
}
 
int Adj(int x)   
{
    for(int i=1;i<=10;i++)
        if(a[x][i]==1 && visited[i]==false)
            return i;
 
    return 0;
}
 
int main()
{
    cout<<"初始化图:"<<endl;
    store_graph();
 
    cout<<"bfs遍历结果:"<<endl;
    bfs_graph();
 
    return 0;
}

转自:图的邻接矩阵和邻接表的比较      bfs与dfs

猜你喜欢

转载自blog.csdn.net/wuhuagu_wuhuaguo/article/details/106744965