zoukankan      html  css  js  c++  java
  • 数据结构基础(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 << "
    BFS: ";
        g.BFS();
        return 0;
    }


  • 相关阅读:
    C++ using namespace std详解
    FlexEdit强大的文本编辑器(免费的!)
    串口扩展方案总结
    LED数码引脚图
    串口扩展方案总结
    C++ using namespace std详解
    Digital Mars Compiler简介及使用
    Digital Mars Compiler简介及使用
    poj1018
    poj3536
  • 原文地址:https://www.cnblogs.com/itrena/p/5926985.html
Copyright © 2011-2022 走看看