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. 【if...else】身高预测

    每个做父母的都关心自己孩子成人后的身高,据有关生理卫生知识与数理统计分析表明,影响小孩成人后的身高的因素包括遗传.饮食习惯与体育锻炼等.小孩成人后的身高与其父母的身高和自身的性别密切相关.设faHei ...

  2. Go 语言递归函数

    递归,就是在运行的过程中调用自己. 语法格式如下: func recursion() { recursion() /* 函数调用自身 */ } func main() { recursion() } ...

  3. JavaScript 函数定义

    JavaScript 使用关键字 function 定义函数. 函数可以通过声明定义,也可以是一个表达式. 函数声明 在之前的教程中,你已经了解了函数声明的语法 : function function ...

  4. 《读书报告 -- Elasticsearch入门 》--简单使用(2)

    <读书报告 – Elasticsearch入门 > ' 第四章 分布式文件存储 这章的主要内容是理解数据如何在分布式系统中存储. 4.1 路由文档到分片 创建一个新文档时,它是如何确定应该 ...

  5. Singular value decomposition

    SVD is a factorization of a real or complex matrix. It has many useful applications in signal proces ...

  6. 拾遗与填坑《深度探索C++对象模型》3.3节

    <深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...

  7. iOS 中捕获截屏操作

    转自:iOS知识小集 在iOS 7后,苹果提供了UIApplicationUserDidTakeScreenshotNotification通知来告诉App用户做了截屏操作.苹果的描述如下: // T ...

  8. [OpenCV]在显示窗口中截图

    [OpenCV]在显示窗口中截图 简介 介绍使用OpenCV实现简单的截图功能.首先阐述实现此功能的基本步骤,然后给出实现代码,最后贴出实验结果以及遇到的问题. 基本步骤 我们需要知道OpenCV使用 ...

  9. 手把手图文教你从Eclipse项目迁移Android Studio

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52937391 从Android的 ...

  10. FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...