图的非递归遍历(深搜和广搜)

//
// Created by Coder
//

#include <iostream>
#include <vector>
#include <stack>
#include <queue>

using namespace std;

class DirectedGraph{

private:
    // 最大顶点数
    const int V = 100000;


    // vector实现的邻接表的定义
    // 不考虑边权,存储类型为int型

    vector<int> e[V];
    int visit[V];

    // 邻接表的初始化操作
    // 将起点为`i`的边链表全部清空
    void init() {
        for (int i=0; i<V; i++) {
            e[i].clear();
            visit[i] = -1;
        }
    }

public:

    bool Visited(int v) {
        return visit[v] != -1;
    }

    void Visit(int v) {
        visit[v] = 1;
        cout<<v<<endl;
    }

    // 增加边
    // 新增顶点`i`到顶点`j`的边
    void AddEdge(int i, int j) {
        e[i].push_back(j);
    }


    // 查询边
    bool SearchEdge( int j, int k) {
        for (int i=0; i<V; i++) {
            //e[i][0] ----- 查询以`i`为起点的第一条边`i->e[i][0]`
            for (int j=0; j<(int)e[i].size(); ++j) {
                if (e[i][j] == k) {     // 查询边`i->k`
                    return true;
                }
            }
        }
        return false;
    }

    int GetFirstNotVisit(int v) {
        for (int j=0; j<e[v].size(); j++) {
            if(!Visited(e[v][j]))
                return j;
        }
        return -1;
    }

    //从v开始深度优先遍历
    void DFS(int v) {
        Visit(v);
        stack<int> s;
        s.push(v);
        while (!s.empty()) {
            //找到下一个待访问的邻接点
            int next = GetFirstNotVisit(s.top());
            if (next != -1) {   //还能继续深搜(未达到最大深度),继续
                //找到栈顶元素第一个未被访问的临接点(也就是更深的邻接点),访问之
                Visit(GetFirstNotVisit(s.top()));
                //入栈
                s.push(GetFirstNotVisit(s.top()));
            } else {    //不能继续深搜下去,回溯
                //出栈(回溯)到能找到有邻接点未被访问的节点
                s.pop();
            }
        }
    }

    //整个图的深搜
    void DFSTraverse() {
        for (int i=0; i<V; i++) {
            if (!Visited(i)) {
                BFS(i);
            }
        }
    }

    //单节点广搜
    void BFS(int v) {
        //访问当前节点
        Visit(v);
        queue<int> s;
        s.push(v);
        while (!s.empty()) {
            //取队首元素
            int front = s.front();
            //出队
            s.pop();
            //对于队首元素,访问其所有未访问的邻接点
            //将未访问的邻接点入栈
            for (int i=0; i<e[front].size(); i++) {
                if (!Visited(e[front][i])) {
                    Visit(e[front][i]);
                    s.push(e[front][i]);
                }
            }
        }
    }

    //整个图的广搜
    void BFSTraverse() {
        for (int i=0; i<V; i++) {
            if (!Visited(i)) {
                BFS(i);
            }
        }
    }
};

更新

加入泛型支持,节点类型要重载=和==运算符,代码有点粗糙,c++水平还是渣。根据严蔚敏的数据结构书中对广搜和深搜的定义书写,代码经过测试。

//
// Created by Coder on 2018/2/13.
//

#include <iostream>
#include <vector>
#include <stack>
#include <queue>

using namespace std;

template <class Type, class Weight>
class DirectedGraph{

private:
    //最大顶点数
    const static int V = 10000;

    //当前的顶点数
    int VertexCount = 0;

    //存储所有的顶点
    vector<Type> vertexs;

    // vector实现的邻接表的定义
    // 注意edge[i]中的每一个元素都表示节点vertex数组中的下标
    // edge[i][j]表示 vertex[i]与vertex[edge[i][j]]有通路
    vector<int> edge[V];
    //weight和数组edge一一对应
    //weight[i][j]表示 vertex[i]与vertex[edge[i][j]]通路的权
    vector<Weight> weight[V];
    int visit[V];

public:

    DirectedGraph() {
        // 邻接表的初始化操作
        // 将起点为`i`的边链表全部清空
        for (int i=0; i<V; i++) {
            edge[i].clear();
            visit[i] = -1;
        }
    }

    bool SearchVertex(Type v) {
        for (int i=0; i<vertexs.size(); i++) {
            if (vertexs[i] == v) {
                return true;
            }
        }
        return false;
    }

    bool InsertVertex(Type v) {
        if(!SearchVertex(v)) {
            vertexs.push_back(v);
            VertexCount++;
            return true;
        }
        return false;
    }

    int FindIndex(Type v) {
        for (int i=0; i<vertexs.size(); i++) {
            if (vertexs[i] == v) {
                return i;
            }
        }
        return -1;
    }

    bool InsertEdge(Type from, Type to, Weight w) {
        int i = FindIndex(from);
        int j = FindIndex(to);
        if(i != -1 && j != -1) {
            //添加边
            edge[i].push_back(j);
            //添加权
            weight[i].push_back(w);
        }
    }

    bool Visited(int index) {
        return visit[index] != -1;
    }

    //访问vertexs[index]
    void Visit(int index) {
        visit[index] = 1;
        cout<<vertexs[index]<<endl;
    }


    // 查询边
    bool SearchEdge( Type from, Type to) {
        int i = FindIndex(from);
        int j = FindIndex(to);
        if (i != -1) {
            for (int k=0; k<(int)edge[i].size(); ++k) {
                if (edge[i][k] == j) {     // 查询边`i->j`
                    return true;
                }
            }
        }
        return false;
    }

    //打印顶点
    void PrintVertex() {
        for (int i=0; i<vertexs.size(); i++) {
            cout<<vertexs[i]<<endl;
        }
    }
    //打印边
    void PrintEdge() {
        for (int i=0; i<VertexCount; i++) {
            for (int j=0; j<edge[i].size(); j++) {
                cout<<vertexs[i]<<"->"<<vertexs[edge[i][j]]<<" weight:"<<weight[i][j]<<endl;
            }
        }
    }

    //返回v第一个没被访问的邻接点下标
    //index是v在vertexs中的下标
    int GetFirstNotVisit(int index) {
        if (index != -1) {
            //遍历v的邻接点
            for (int j=0; j<edge[index].size(); j++) {
                if(!Visited(edge[index][j]))
                    return edge[index][j];
            }
        }
        return -1;
    }

    //从v开始深度优先遍历
    void DFS(int index) {
        //访问该节点
        Visit(index);
        //存储节点的下标
        stack<int> s;
        s.push(index);
        while (!s.empty()) {
            //找到下一个待访问的邻接点下标
            int next = GetFirstNotVisit(s.top());
            if (next != -1) {   //还能继续深搜(未达到最大深度),继续
                //找到栈顶元素第一个未被访问的临接点(也就是更深的邻接点),访问之
                Visit(next);
                //入栈
                s.push(next);
            } else {    //不能继续深搜下去,回溯
                //出栈(回溯)到能找到有邻接点未被访问的节点
                s.pop();
            }
        }
    }

    //整个图的深搜
    void DFSTraverse() {
        for (int i=0; i<VertexCount; i++) {
            if (!Visited(i)) {
                DFS(i);
            }
        }
    }

    //单节点广搜
    void BFS(int index) {
        //访问当前节点
        Visit(index);
        queue<int> s;
        s.push(index);
        while (!s.empty()) {
            //取队首元素
            int front = s.front();
            //出队
            s.pop();
            //对于队首元素,访问其所有未访问的邻接点
            //将未访问的邻接点入栈
            for (int i=0; i<edge[front].size(); i++) {
                if (!Visited(edge[front][i])) {
                    Visit(edge[front][i]);
                    s.push(edge[front][i]);
                }
            }
        }
    }

    //整个图的广搜
    void BFSTraverse() {
        for (int i=0; i<VertexCount; i++) {
            if (!Visited(i)) {
                BFS(i);
            }
        }
    }
};

int main() {
    DirectedGraph<char, int> graph;
    int total, weight;
    char from, to;
    cin>>total;
    for (int i=0; i<total; i++) {
        cin>>from>>to;
        graph.InsertVertex(from);
        graph.InsertVertex(to);
        graph.InsertEdge(from, to, weight);
        graph.InsertEdge(to, from, weight);
    }
//    graph.PrintVertex();
//    graph.PrintEdge();
//    graph.DFSTraverse();
    graph.BFSTraverse();
}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/aNoobCoder/article/details/79321561
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞