C++实现图的遍历算法(DFS,BFS)的示例代码

 更新时间:2022年07月25日 10:20:32   作者:小张﹉  
本文给大家带来的是图遍历的算法,DFS(深度优先遍历),BFS(广度优先遍历)。这两个算法是比较重要和常用的算法,但是在图中的实现只是最基本的操作,快跟随小编一起学习一下吧

图的定义

图由顶点集V(G)和边集E(G)组成,记为G=(V,E)。其中E(G)是边的有限集合,边是顶点的无序对(无向图)或有序对(有向图)。对于有向图来说,E(G)是有向边(也称弧(Arc))的有限集合,弧是顶点的有序对,记为<v,w>,v、w是顶点,v为弧尾(箭头根部),w为弧头(箭头处)。对于无向图来说,E(G)是边的有限集合,边是顶点的无序对,记为(v, w)或者(w, v),并且(v, w)=(w,v)。

图的相关术语

①顶点(Vertex):图中的数据元素。

②顶点v的度:与v相关联的边的数目;

③顶点v的出度:以v为起点有向边数;

④顶点v的入度:以v为终点有向边数。

⑤边:顶点之间的逻辑关系用边来表示,边集可以是空的。

⑥无向边(Edge):若顶点V1到V2之间的边没有方向,则称这条边为无向边。

⑦无向图(Undirected graphs):图中任意两个顶点之间的边都是无向边。(A,D)=(D,A)

⑧有向边:若从顶点V1到V2的边有方向,则称这条边为有向边,也称弧(Arc)。用<V1,V2>表示,V1为狐尾(Tail),V2为弧头(Head)。(V1,V2)≠(V2,V1)。

⑨有向图(Directed graphs):图中任意两个顶点之间的边都是有向边。

注意:无向边用“()”,而有向边用“< >”表示。

⑩简单图:图中不存在顶点到其自身的边,且同一条边不重复出现。

⑪无向完全图:无向图中,任意两个顶点之间都存在边。

⑫有向完全图:有向图中,任意两个顶点之间都存在方向互为相反的两条弧。

⑬稀疏图:有很少条边。

⑭稠密图:有很多条边。

⑮权(Weight):与图的边或弧相关的数。

⑯网(Network):带权的图。

⑰连通图:图中任意两个顶点都是连通的。

⑱极大连通子图:该子图是G连通子图,将G的任何不在该子图的顶点加入,子图将不再连通。

⑲极小连通子图:该子图是G的连通子图,在该子图中删除任何一条边,子图都将不再连通。

图的创建(邻接矩阵)---结构体

typedef struct
{
    //用来存放顶点
    int vexs[MAX];
    //二维数组:用来存放两点之间的关系
    int arcs[MAX][MAX];
    //图的顶点数和边数
    int vexsum, arcsnum;
}AMGraph,*StrAMGraph;

图的创建(邻接矩阵)---邻接矩阵的创建

int locate(AMGraph&G, int n)
{
    for (int i = 0; i < G.vexsum; i++)
    {
        if (G.vexs[i] == n)
        {
            return i;
        }
    }
}
 
//创建邻接矩阵
void Creat(AMGraph&G)
{
    int v1 = 0, v2 = 0, w = 0;
    cin >> G.vexsum >> G.arcsnum;
    for (int i = 0; i < G.vexsum; i++)
    {
        cin >> G.vexs[i];
    }
    for (int i = 0; i < G.vexsum; i++)
    {
        for (int j = 0; j < G.vexsum; j++)
        {
            G.arcs[i][j] = 0;
        }
    }
    for (int k = 0; k < G.arcsnum; k++)
    {
        cin >> v1 >> v2 >> w;
        int i = locate(G, v1);
        int j = locate(G, v2);
        G.arcs[i][j] = w;
    }
}

图的创建(邻接表)---结构体

typedef struct ArcNode
{
    int Adjust;
    struct ArcNode *next;
}AcrNode,*StrAcrNode;
 
 
typedef struct
{
    int data;
    StrAcrNode next;
}HeadNode, *StrHeadNode;
 
 
typedef struct 
{
    HeadNode arr[MAX];
    int acsrnum, vexsnum;
}ALGraph, *StrALGraph;

图的创建(邻接表)---邻接表的创建

int locate1(ALGraph&G, int n)
{
    for (int i = 0; i < G.vexsnum; i++)
    {
        if (G.arr[i].data == n)
        {
            return i;
        }
    }
}
 
void CreatALGraph(ALGraph&G)
{
    int v1 = 0, v2 = 0, w = 0;
    cin >> G.vexsnum >> G.acsrnum;
    for (int i = 0; i < G.vexsnum; i++)
    {
        cin >> G.arr[i].data;
        G.arr[i].next = NULL;
    }
    for (int k = 0; k < G.acsrnum; k++)
    {
        cin >> v1 >> v2;
        int i = locate1(G, v1);
        int j = locate1(G, v2);
        StrAcrNode p1;
        p1 = new AcrNode;
        p1->next = G.arr[i].next;
    }
}

对邻接矩阵进行深度优先遍历

//对邻接矩阵进行深度优先遍历
void DFS(AMGraph&G, int n)
{
    cout << G.vexs[n] << " ";
    visit[n] = 1;
    for (int i = 0; i < G.vexsum; i++)
    {
        if (G.arcs[n][i] != 1 && visit[i] != 1)
        {
            DFS(G, G.arcs[n][i]);
        }
    }
}

对邻接矩阵进行广度优先遍历

queue<int> qu;
//对邻接矩阵进行广度优先遍历
void BFS(AMGraph&G, int n)
{
    cout << G.vexs[n] << " ";
    qu.push(n);
    while (!qu.empty())
    {
        int m = qu.front();
        qu.pop();
        for (int i = 0; i < G.vexsum; i++)
        {
            if (visit[i] != 1 && G.arcs[m][i] != 1)
            {
                cout << G.vexs[i] << " ";
                visit[i] = 1;
                qu.push(i);
            }
        }
    }
}

对邻接表进行深度优先遍历 

void DFS1(ALGraph&G, int n)
{
    cout << G.arr[n].data << " ";
    visit3[n] = 1;
    StrAcrNode p1;
    p1 = G.arr[n].next;
    while (p1)
    {
        int w = p1->Adjust;
        if (visit3[w] != 1)
        {
            DFS1(G, w);
        }
        p1 = p1->next;
    }
}
 
queue<int> qu1;

对邻接表进行广度优先遍历 

queue<int> qu1;
void BFS(ALGraph&G, int n)
{
    cout << G.arr[n].data << " ";
    visit4[n] = 1;
    qu1.push(n);
    StrAcrNode p1;
    p1 = G.arr[n].next;
    while (!qu1.empty())
    {
        qu1.pop();
        int w = p1->Adjust;
        while (p1)
        {
            if (visit4[w] != 1)
            {
                qu1.push(w);
                visit4[w] = 1;
            }
            p1 = p1->next;
        }
    }
}

整体代码

#include<iostream>
#include<queue>
using namespace std;
const int MAxInt = 10;
int visit[MAxInt];
 
typedef struct
{
    int vexs[MAxInt];
    int arcs[MAxInt][MAxInt];
    int arcnum, vexsnum;
}AMGraph;
 
int locate(AMGraph&G, int n)
{
    for (int i = 0; i < G.vexsnum; i++)
    {
        if (G.vexs[i] == n)
        {
            return i;
        }
    }
}
 
void Creat(AMGraph&G)
{
    int v1 = 0, v2 = 0, w = 0;
    cin >> G.vexsnum >> G.arcnum;
    for (int i = 0; i < G.vexsnum; i++)
    {
        cin >> G.vexs[i];
    }
    for (int i = 0; i < G.vexsnum; i++)
    {
        for (int j = 0; j < G.vexsnum; j++)
        {
            G.arcs[i][j] = MAxInt;
        }
    }
    for (int k = 0; k < G.arcnum; k++)
    {
        cin >> v1 >> v2 >> w;
        int i = locate(G, v1);
        int j = locate(G, v2);
        G.arcs[i][j] = w;
        G.arcs[j][i] = w;
    }
}
 
 
 
queue<int> qu;
void BFS(AMGraph G, int v)
{
    cout << G.vexs[v];
    qu.push(v);
    visit[v] = 1;
    while (!qu.empty())
    {
        int w = qu.front();
        qu.pop();
        for (int i = 0; i < G.vexsnum; i++)
        {
            if (visit[i] != 1 && G.arcs[w][i] != MAxInt)
            {
                cout << G.vexs[i] << " ";
                visit[i] = 1;
                qu.push(i);
            }
        }
    }
}
 
int main()
{
    AMGraph G;
    Creat(G);
    cout << "对图进行广度优先遍历的结果为" << endl;
    BFS(G, 1);
    return 0;
}

注意 :这里的代码是创建一个邻接矩阵来对图进行广度优先遍历,对图进行深度优先遍历以及临界表实现对图进行广度优先遍历,对图进行深度优先遍历大家都可以通过上面的代码块进行自由组合实现,这里就不进行一一实现。

结果展示

以上就是C++实现图的遍历算法(DFS,BFS)的示例代码的详细内容,更多关于C++ DFS BFS的资料请关注脚本之家其它相关文章!

相关文章

  • C++使用一棵红黑树同时封装出map和set实例代码

    C++使用一棵红黑树同时封装出map和set实例代码

    红黑树(Red Black Tre)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组,下面这篇文章主要给大家介绍了关于C++使用一棵红黑树同时封装出map和set的相关资料,需要的朋友可以参考下
    2023-04-04
  • 浅谈C语言编程中程序的一些基本的编写优化技巧

    浅谈C语言编程中程序的一些基本的编写优化技巧

    这篇文章主要介绍了C语言编程中程序的一些基本的编写优化技巧,文中涉及到了基础的C程序内存方面的知识,非常推荐!需要的朋友可以参考下
    2016-02-02
  • C语言深入探索数据类型的存储

    C语言深入探索数据类型的存储

    使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。您可能需要存储各种数据类型的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么
    2022-07-07
  • C++浅析内联函数的使用

    C++浅析内联函数的使用

    为了消除函数调用的时空开销,C++ 提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开。这种在函数调用处直接嵌入函数体的函数称为内联函数(Inline Function),又称内嵌函数或者内置函数
    2022-05-05
  • C++ cin不同状态详细讲解

    C++ cin不同状态详细讲解

    cin是C++编程语言中的标准输入流对象,即istream类的对象。cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout是流的对象,即ostream类的对象,cerr是标准错误输出流的对象,也是ostream类的对象
    2022-10-10
  • C语言由浅入深讲解文件的操作下篇

    C语言由浅入深讲解文件的操作下篇

    C语言具有操作文件的能力,比如打开文件、读取和追加数据、插入和删除数据、关闭文件、删除文件等。与其他编程语言相比,C语言文件操作的接口相当简单和易学
    2022-04-04
  • C语言中scanf与scanf_s函数的使用详解

    C语言中scanf与scanf_s函数的使用详解

    本文主要介绍了C语言中scanf与scanf_s函数的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C++遍历磁盘驱动器的示例代码

    C++遍历磁盘驱动器的示例代码

    这篇文章主要介绍了C++遍历磁盘驱动器的示例代码,帮助大家更好的理解和使用c++,感兴趣的朋友可以了解下
    2021-01-01
  • C++实现字符串删除字符后逆序输出

    C++实现字符串删除字符后逆序输出

    这篇文章主要为大家详细介绍了C++实现字符串删除字符后逆序输出,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • 基于MATLAB神经网络图像识别的高识别率代码

    基于MATLAB神经网络图像识别的高识别率代码

    今天小编就为大家分享一篇关于基于MATLAB神经网络图像识别的高识别率代码,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03

最新评论