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. JDBC:从原理到应用

    一.是为何物 1.概念 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用J ...

  2. Django网站制作

    创建mysite目录 django-admin.py startproject mysite这个命令作用是:这将创建在当前目录创建一个mysite目录 前提是从命令行上cd到你想储存你代码的目录,然后 ...

  3. RxJava(十一)defer操作符实现代码支持链式调用

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52597643 本文出自:[余志强的博客] 一.前言 现在越来越多An ...

  4. android开发中使用到的一些设计者模式

    单例模式 概念:确保一个类只有一个实例,并且自行实例化并向整个系统提供整个实例. public class Singleton { private static volatile Singleton ...

  5. Oracle11g R2创建PASSWORD_VERIFY_FUNCTION对应密码复杂度验证函数步骤

    Oracle11g R2创建PASSWORD_VERIFY_FUNCTION对应密码复杂度验证函数步骤 运行测试环境:数据库服务器Oracle Linux 5.8 + Oracle 11g R2数据库 ...

  6. Android必知必会-长按返回健退出

    背景 平常比较常见的都是一定时间间隔内按两次返回键来退出应用,并且第一次点击会有相应的提示,网上资料比较多,这里写一下,长按返回键退出. 实现 实现的方案常用的有两个: 重写dispatchKeyEv ...

  7. 物料分类新增&更新

    --新增 INV_ITEM_CATEGORY_PUB.Create_Category ( p_api_version IN NUMBER, p_init_msg_list IN VARCHAR2 DE ...

  8. 详解EBS接口开发之供应商导入

    (一)供应商常用标准表简介 1.1   常用标准表 如下表中列出了与供应商相关的表和说明: 表名 说明 其他信息 ap_suppliers 供应商头表 供应商的头信息如:供应商名.供应商编码.税号等 ...

  9. 一个ExtJS实例

    聊聊ExtJS 这几天接触了一个项目 前台用的是extjs 发现这个东西还是有点意思的  就把前台的部分 剥离了下来 有兴趣的朋友可以当做模板学习 不多说先上效果图 这篇文章 可以看作是ext知识的一 ...

  10. Dynamics CRM2015 2015版本可用的OData Query Designer工具

    2015后很多工具无法使用,包括2011版的OData Query Designer,这里介绍一款可用的工具,Dynamics XRM Tools for CRM 2015,下载地址:https:// ...