DFS

从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到(使用堆栈).

//使用邻接矩阵存储的无向图的深度优先遍历
template <typename Type>
void Graph<Type>::DFS()
{
    stack<int> iStack;

    showVertex(0);
    vertexList[0]->wasVisted = true;
    iStack.push(0);

    while (!iStack.empty())
    {
        int top = iStack.top();
        int v = getAdjUnvisitedVertex(top);
        if (v == -1)
        {
            iStack.pop();
        }
        else
        {
            showVertex(v);
            vertexList[v]->wasVisted = true;
            iStack.push(v);
        }
    }

    //使其还可以再深/广度优先搜索
    for (int i = 0; i < nVerts; ++i)
        vertexList[i]->wasVisted = false;
}

BFS

从图中的某个顶点V0出发,并在访问此顶点之后依次访问V0的所有未被访问过的邻接点,之后按这些顶点被访问的先后次序依次访问它们的邻接点,直至图中所有和V0有路径相通的顶点都被访问到.

若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止(使用队列)。

//使用邻接矩阵存储的无向图的广度优先遍历
template <typename Type>
void Graph<Type>::BFS()
{
    queue<int> iQueue;

    showVertex(0);
    vertexList[0]->wasVisted = true;
    iQueue.push(0);

    while (!iQueue.empty())
    {
        int front = iQueue.front();
        iQueue.pop();
        int v = getAdjUnvisitedVertex(front);
        while (v != -1)
        {
            showVertex(v);
            vertexList[v]->wasVisted = true;
            iQueue.push(v);
            v = getAdjUnvisitedVertex(front);
        }
    }

    for (int i = 0; i < nVerts; ++i)
        vertexList[i]->wasVisted = false;
}

附-完整代码

const int MAX_VERTS = 20;
//顶点
template <typename Type>
class Vertex
{
public:
    Vertex(const Type &_node = Type())
        : node(_node), wasVisted(false) {}

public:
    bool wasVisted;	//增加一个访问位
    Type node;
};
//图
template <typename Type>
class Graph
{
public:
    Graph();
    ~Graph();

    void addVertex(const Type &vertex);
    void addEdge(int start, int end);
    void printMatrix();
    void showVertex(int v);
    void DFS();
    void BFS();

private:
    int getAdjUnvisitedVertex(int v);

private:
    Vertex<Type>* vertexList[MAX_VERTS];
    int nVerts;
    int adjMatrix[MAX_VERTS][MAX_VERTS];
};
template <typename Type>
void Graph<Type>::DFS()
{
    stack<int> iStack;

    showVertex(0);
    vertexList[0]->wasVisted = true;
    iStack.push(0);

    while (!iStack.empty())
    {
        int top = iStack.top();
        int v = getAdjUnvisitedVertex(top);
        if (v == -1)
        {
            iStack.pop();
        }
        else
        {
            showVertex(v);
            vertexList[v]->wasVisted = true;
            iStack.push(v);
        }
    }

    //使其还可以再深度优先搜索
    for (int i = 0; i < nVerts; ++i)
        vertexList[i]->wasVisted = false;
}

template <typename Type>
void Graph<Type>::BFS()
{
    queue<int> iQueue;

    showVertex(0);
    vertexList[0]->wasVisted = true;
    iQueue.push(0);

    while (!iQueue.empty())
    {
        int front = iQueue.front();
        iQueue.pop();
        int v = getAdjUnvisitedVertex(front);
        while (v != -1)
        {
            showVertex(v);
            vertexList[v]->wasVisted = true;
            iQueue.push(v);
            v = getAdjUnvisitedVertex(front);
        }
    }

    for (int i = 0; i < nVerts; ++i)
        vertexList[i]->wasVisted = false;
}
//获取下一个尚未访问的连通节点
template <typename Type>
int Graph<Type>::getAdjUnvisitedVertex(int v)
{
    for (int j = 0; j < nVerts; ++j)
    {
        //首先是邻接的, 并且是未访问过的
        if ((adjMatrix[v][j] == 1) &&
                (vertexList[j]->wasVisted == false))
            return j;
    }
    return -1;
}
//打印节点信息
template <typename Type>
void Graph<Type>::showVertex(int v)
{
    cout << vertexList[v]->node << ' ';
}

template <typename Type>
Graph<Type>::Graph():nVerts(0)
{
    for (int i = 0; i < MAX_VERTS; ++i)
        for (int j = 0; j < MAX_VERTS; ++j)
            adjMatrix[i][j] = 0;
}
template <typename Type>
Graph<Type>::~Graph()
{
    for (int i = 0; i < nVerts; ++i)
        delete vertexList[i];
}
template <typename Type>
void Graph<Type>::addVertex(const Type &vertex)
{
    vertexList[nVerts ++] = new Vertex<Type>(vertex);
}
template <typename Type>
void Graph<Type>::addEdge(int start, int end)
{
    //无向图
    adjMatrix[start][end] = 1;
    adjMatrix[end][start] = 1;
}
template <typename Type>
void Graph<Type>::printMatrix()
{
    for (int i = 0; i < nVerts; ++i)
    {
        for (int j = 0; j < nVerts; ++j)
            cout << adjMatrix[i][j] << ' ';
        cout << endl;
    }
}

//测试代码
int main()
{
    Graph<char> g;
    g.addVertex('A');   //0
    g.addVertex('B');   //1
    g.addVertex('C');   //2
    g.addVertex('D');   //3
    g.addVertex('E');   //4

    g.addEdge(0, 1);    //A-B
    g.addEdge(0, 3);    //A-D
    g.addEdge(1, 0);    //B-A
    g.addEdge(1, 4);    //B-E
    g.addEdge(2, 4);    //C-E
    g.addEdge(3, 0);    //D-A
    g.addEdge(3, 4);    //D-E
    g.addEdge(4, 1);    //E-B
    g.addEdge(4, 2);    //E-C
    g.addEdge(4, 3);    //E-D

    g.printMatrix();

    cout << "DFS: ";
    g.DFS();
    cout << "\nBFS: ";
    g.BFS();
    return 0;
}

数据结构基础(21) --DFS与BFS的更多相关文章

  1. Java数据结构——图的DFS和BFS

    1.图的DFS: 即Breadth First Search,深度优先搜索是从起始顶点开始,递归访问其所有邻近节点,比如A节点是其第一个邻近节点,而B节点又是A的一个邻近节点,则DFS访问A节点后再访 ...

  2. [数据结构]图的DFS和BFS的两种实现方式

    深度优先搜索 深度优先搜索,我们以无向图为例. 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发, ...

  3. 算法与数据结构基础 - 深度优先搜索(DFS)

    DFS基础 深度优先搜索(Depth First Search)是一种搜索思路,相比广度优先搜索(BFS),DFS对每一个分枝路径深入到不能再深入为止,其应用于树/图的遍历.嵌套关系处理.回溯等,可以 ...

  4. 【数据结构与算法笔记04】对图搜索策略的一些思考(包括DFS和BFS)

    图搜索策略 这里的"图搜索策略"应该怎么理解呢? 首先,是"图搜索",所谓图无非就是由节点和边组成的,那么图搜索也就是将这个图中所有的节点和边都访问一遍. 其次 ...

  5. 算法与数据结构基础 - 广度优先搜索(BFS)

    BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...

  6. Clone Graph leetcode java(DFS and BFS 基础)

    题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. ...

  7. 数据结构(12) -- 图的邻接矩阵的DFS和BFS

    //////////////////////////////////////////////////////// //图的邻接矩阵的DFS和BFS ////////////////////////// ...

  8. 数据结构(11) -- 邻接表存储图的DFS和BFS

    /////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...

  9. 列出连通集(DFS及BFS遍历图) -- 数据结构

    题目: 7-1 列出连通集 (30 分) 给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递 ...

随机推荐

  1. 使用Boost program_options控制程序输入

    简介 很多人使用界面来输入数据,本文的程序介绍如何使用Boost的program_options控制输入. 程序中使用了: 1. 短选项 2. 可以指定多个参数的选项 程序 #include < ...

  2. Spring动态切换多数据源解决方案

    Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时 ...

  3. MacOS和iOS开发中异步调用与多线程的区别

    很多童鞋可能对Apple开发中的异步调用和多线程的区别不是太清楚,这里本猫将用一些简单的示例来展示一下它们到底直观上有神马不同. 首先异步调用可以在同一个线程中,也可以在多个不同的线程中.每个线程都有 ...

  4. scheme深拷贝和浅拷贝探索

    > (define a '(1 2 3)) > (define b (cons a '())) > b (( )) > (set-car! (car b) ) > b ( ...

  5. Android fragment(片段)构建灵活的UI

    在以支持多种屏幕尺寸为目标设计应用时,您可以在不同的布局配置中重复使用您的fragment 从而根据可用的屏幕空间优化用户体验. 例如,在手机设备上,由于采用单窗格用户界面,因此可能更适合一次只显示一 ...

  6. Gazebo機器人仿真學習探索筆記(二)基本使用說明

    在完成Gazebo7安裝後,需要熟悉Gazebo,方便之後使用. 部分源代碼可以參考:https://bitbucket.org/osrf/gazebo/src/ 如果還沒有安裝請參考之前內容完成安裝 ...

  7. Anakia 转换xml文档为其他格式

    一.简介 Anakia 使用JDOM 和Velocity将XML文档转换为特定格式的文档 二.解析xml文档方法 1.DOM java jdk,xml-api.jar 需要加载整个xml文档来构建层次 ...

  8. Swift快速给Cocoa库内置类添加便捷初始化器

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Cocoa中的NSShadow类默认没有我们需要的实例方法,为 ...

  9. iOS日历中给一个事件添加多个提醒

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) iOS自带的日历应用中,我们最多只能给一个事件设置2个提醒,但 ...

  10. Eclipse中如何快速查看jar包中 的class源码

    我们查看jar源码时,一般是安装个jd-gui,把jar拷出来,然后从jd-gui中打开jar再查看源码,这个过程不免有些麻烦,当然,本篇所讲的快速查看的方法也没什么高科技手段,只是将jd-gui集成 ...