数据结构基础(21) --DFS与BFS

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;
}
时间: 2024-11-01 02:24:14

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

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. OJ's undirected graph serialization: Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node label and each n

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

BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数据结构基础 - 队列(Queue) 最直观的BFS应用是图和树的遍历,其中图常用邻接表或矩阵表示,例如 LeetCode题目 690. Employee Importance: // LeetCode 690. Employee Importance/* class Employee { publi

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

/////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS /////////////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> #include <queue> using namespace std; //图的邻接表表示法

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

//////////////////////////////////////////////////////// //图的邻接矩阵的DFS和BFS //////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> #include <queue> #define MaxVertexNum 100 //最大顶点数 //#define INFINI

学习笔记:图的DFS和BFS的两种搜索办法

  在学习图结构的过程中,DFS和BFS是两种不同的遍历方式,其寻找元素具有不同的优点和缺陷. BFS被称作广度优先算法, 在遍历整个图的过程中,BFS将采用入队的方式进行,值得一提的是,这和树结构中的层序遍历有很大的相似之处. 在层序遍历中,将父亲节点入队后,在父亲节点出队后,将其儿子节点入队. 同理在图的BFS遍历中,先让BFS的首元素入队,在收元素入队后将他的儿子节点入队,放能够实现BFS搜索,他们的整体思想是一样的. 1 void TraversalGraph_BFS(LGraph Gr

搜索分析(DFS、BFS、递归、记忆化搜索)

搜索分析(DFS.BFS.递归.记忆化搜索) 1.线性查找 在数组a[]={0,1,2,3,4,5,6,7,8,9,10}中查找1这个元素. (1)普通搜索方法,一个循环从0到10搜索,这里略. (2)递归(从中间向两边) 1 //递归一定要写成记忆化递归 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool vis[11]; 5 int count1=0; 6 7 void search(int n){ 8 count1++; 9

OC基础(21)

Foundation框架介绍 NSString基本概念 字符串读写 字符串比较 字符串搜索 字符串截取 字符串替换 字符串与路径 字符串与基本数据类型转换 *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; } a.absent { color: #cc0000; } a.anchor { display: bloc

算法与数据结构基础10:C++实现——拓扑排序

一 定义 拓扑排序是对有向无环图(Directed Acyclic Graph简称DAG)顶点的一种排序, 它使得如果存在一条从顶点A到顶点B的路径,那么在排序中B出现在A的后面. 二 先决条件 能够进行拓扑排序图有两个先决条件:有向.无环,即有向无环图. 三 偏序全序 连通图:任意两点之间都存在至少一条边 偏序:非连通图(有向无环图满足偏序关系) 全序:单连通图 四 结果唯一性 对于仅满足偏序关系的有向无环图中,因为有两个点之间的关系是不确定的,所以导致排序的结果是不唯一的. 满足全序关系的有

数据结构基础温故-6.查找(上):基本查找与树表查找

只要你打开电脑,就会涉及到查找技术.如炒股软件中查股票信息.硬盘文件中找照片.在光盘中搜DVD,甚至玩游戏时在内存中查找攻击力.魅力值等数据修改用来作弊等,都要涉及到查找.当然,在互联网上查找信息就更加是家常便饭.查找是计算机应用中最常用的操作之一,也是许多程序中最耗时的一部分,查找方法的优劣对于系统的运行效率影响极大.因此,本篇讨论一些查找方法. 一.顺序查找 1.1 基本思想 顺序查找(Sequential Search)又叫线性查找,是最基本的查找技术,它的查找过程是:从表中第一个(或最后