//图的存储结构:
const int MAXSIZE = 10;
//邻接矩阵
template<class T>
class MGraph {
public:
    MGraph(T a[], int n, int e);
    void DFS(int v);
    void BFS(int v);
private:           //edge为边用来表示无向图,arc为弧用来表示有向图,vertex为顶点
    T vertex[MAXSIZE];
    int arc[MAXSIZE][MAXSIZE];
    int edge[MAXSIZE][MAXSIZE];
    int vNum, arcNum,eNum;
    bool* visited;     //DFS使用
};
template<class T>
MGraph<T>::MGraph(T a[], int v, int e) {     //n为顶点个数,e为边的个数,a[]为各顶点值
    vNum = v;            //将顶点个数,边个数,顶点值放入类中属性
    arcNum = e;
    visited = new bool[v];
    memset(visited, false, sizeof(bool) * v);
    for (int k = 0; k < v; k++) {    
        vertex[k] = a[k];
    }
    for (int k = 0; k < v; k++) {    //先将邻接矩阵初始化
        for (int j = 0; j < v; j++) {
            arc[k][j] = 0;
        }
    }
    for (int k = 0,i=0,j=0; k < e; k++) {  //这里是无向图的邻接矩阵,输入相连的两个顶点
        cin >> i >> j;
        arc[j-1][i-1] = arc[i-1][j-1] = 1;
    }
}

//邻接表,同样以无向图为例,边用arc表示
struct ArcNode {    //边的数据结构,存储边信息和下一条边
    int adjvex;   //相邻的顶点
    ArcNode* nextarc;
};
struct VertexNode {   //顶点的数据结构,存储顶点信息和下一条边
    int vertex;
    ArcNode* firstarc;
};
template<class T>
class ALGraph {
public:
    ALGraph(T a[], int n, int e);
    //~ALGraph();
    void DFS(int v);
    void BFS(int v);
private:
    VertexNode adjlist[MAXSIZE];
    int vNum, arcNum;
    bool* visited;
};
template<class T>
ALGraph<T>::ALGraph(T a[], int v, int e) {
    vNum = v;
    arcNum = e;
    visited = new bool[v];
    memset(visited, false, sizeof(bool) * v);
    for (int i = 0; i < v; i++) {  //对顶点表进行初始化
        adjlist[i].vertex = a[i];
        adjlist[i].firstarc = NULL;
    }
    for (int k = 0,i=0,j=0; k < e; k++) {  //这里是无向图,如果有向图的话,则为顶点i指向j
        cin >> i >> j;               //注意这里的e是每个顶点连接的边的总和,将无向看成有双箭头的有向(实际不适合表示无向图)
        ArcNode* s = new ArcNode;
        s->adjvex = j;                      //这里使用的是头插入法
        s->nextarc = adjlist[i-1].firstarc;
        adjlist[i-1].firstarc = s;
    }
}
//补充:邻接表适合表示有向图,还有一种逆邻接表表示法,与邻接表的出为指向方向相反,逆邻接表类似于入边表

//十字链表,只提供节点的存储结构
struct VertexNodeC {
    int Vertex;
    ArcNode* firstin;
    ArcNode* firstout;
};
struct ArcNodeC {
    int headvex,tailvex;
    ArcNode* hlink;
};

//边集数组,比较常用,使用两个一维数组存储,一个数组存储顶点,一个数组存储起点,终点,权值
struct ArcNodeE {
    int headvex;
    int tailvex;
    int weight;
};

//图的遍历:DFS与BFS
//DFS深度优先搜索,类似于二叉树的前序遍历,先从一条支路到结尾,然后一步步回溯寻找还未访问过的节点
//邻接矩阵和邻接表两种存储结构的dfs
//两种存储结构的dfs比较
//邻接矩阵的时间复杂度 n
//邻接表的时间复杂度 n+e 栈深度 n 空间复杂度 n
template<class T>
void MGraph<T>::DFS(int v) {
    cout << vertex[v];
    visited[v] = true;    //将访问过的顶点标记为访问过
    for (int j = 0; j < vNum; j++) {       //按照邻接矩阵的特性,根据标记来深入搜索
        if (arc[v][j] == 1 && visited[j] == false) {
            DFS(j);
        }
    }
}
template<class T>
void ALGraph<T>::DFS(int v) {  //根据邻接表的连接,从顶点第一个边节点转为顶点节点,并标记是否访问,然后一步步回溯看是否有未访问的相邻节点
    cout << adjlist[v].vertex;
    visited[v] = true;
    ArcNode* p = adjlist[v].firstarc;
    while (p) {
        if (visited[p->adjvex] == false) {
            DFS(p->adjvex);
        }
        p = p->nextarc;
    }
}

//BFS广度优先搜索,类似于树的层序遍历,使用队列逻辑结构
//分别用邻接矩阵和邻接表描述
//邻接矩阵时间复杂度 n
//邻接表时间复杂度 n+e 空间复杂度 n
template<class T>
void MGraph<T>::BFS(int v) {
    int queue[MAXSIZE];
    int f = 0, r = 0;
    cout << vertex[v];
    visited[v] = true;
    queue[++r] = v;
    while (f != r) {      //当头尾相等时队列为空,表示队列为空
        v = queue[++f];
        for (int j = 0; j < vNum; j++) {
            if (arc[v][j] == 1 && visited[j] == false) {
                cout << vertex[j];
                visited[j] = true;
                queue[++r] = j;
            }
        }
    }
}
template<class T>
void ALGraph<T>::BFS(int v) {
    int queue[MAXSIZE];
    int f = 0, r = 0;
    cout << adjlist[v].vertex;
    visited[v] = true;
    queue[++r] = v;
    while (r!=f) {
        v = queue[++f];
        ArcNode *p = adjlist[v].firstarc;
        while (p) {
            int j = p->adjvex;
            if (visited[j] == false) {
                cout << adjlist[j].vertex;
                visited[j] = true;
                queue[++r] = j;
            }
            p = p->nextarc;
        }
    }
}
关于图的4中基本算法放在单独一篇,Prim,Kruskal,Floyd,Dijkstra

图的数据结构的实现与遍历(DFS,BFS)的更多相关文章

  1. 图的遍历[DFS][BFS]

    #include<iostream> #include<iostream> #include<cstring> #include<queue> #inc ...

  2. 列出连通集(DFS及BFS遍历图) -- 数据结构

    题目: 7-1 列出连通集 (30 分) 给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递 ...

  3. 图的两种遍历:DFS&BFS

    DFS和BFS在图中的应用: 图连通性判定:路径的存在性:图中是否存在环:求图的最小生成树:求图的关键路径:求图的拓扑排序. DFS:简单的说,先一直往深处走,直到不能再深了,再从另一条路开始往深处走 ...

  4. 图的遍历——DFS和BFS模板(一般的图)

    关于图的遍历,通常有深度优先搜索(DFS)和广度优先搜索(BFS),本文结合一般的图结构(邻接矩阵和邻接表),给出两种遍历算法的模板 1.深度优先搜索(DFS) #include<iostrea ...

  5. 数据结构与算法之PHP用邻接表、邻接矩阵实现图的广度优先遍历(BFS)

    一.基本思想 1)从图中的某个顶点V出发访问并记录: 2)依次访问V的所有邻接顶点: 3)分别从这些邻接点出发,依次访问它们的未被访问过的邻接点,直到图中所有已被访问过的顶点的邻接点都被访问到. 4) ...

  6. 图的深度优先遍历(DFS)和广度优先遍历(BFS)

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  7. PAT Advanced 1034 Head of a Gang (30) [图的遍历,BFS,DFS,并查集]

    题目 One way that the police finds the head of a gang is to check people's phone calls. If there is a ...

  8. 图的遍历DFS

    图的遍历DFS 与树的深度优先遍历之间的联系 树的深度优先遍历分为:先根,后根 //树的先根遍历 void PreOrder(TreeNode *R){ if(R!=NULL){ visit(R); ...

  9. 算法学习记录-图(DFS BFS)

    图: 目录: 1.概念 2.邻接矩阵(结构,深度/广度优先遍历) 3.邻接表(结构,深度/广度优先遍历) 图的基本概念: 数据元素:顶点 1.有穷非空(必须有顶点) 2.顶点之间为边(可空) 无向图: ...

随机推荐

  1. Spring Boot 使用 JAX-WS 调用 WebService 服务

    除了 CXF 我们还可以使用 Spring Boot 自身默认的组件 JAX-WS 来实现 WebService 的调用. 本项目源码 github 下载 1 新建 Spring Boot Maven ...

  2. 14. 深入解析Pod对象(一)

    14. 深入解析Pod对象(一) """ 通过前面的讲解,大家应该都知道: Pod,而不是容器,它是 Kubernetes 项目中的最小编排单位.将这个设计落实到 API ...

  3. HttpClient和HtmlUnit的比较总结以及使用技巧

    本文转自: https://blog.csdn.net/zstu_cc/article/details/39250903 https://blog.csdn.net/zstu_cc/article/d ...

  4. vue项目注意事项

    vue项目注意事项 1. 文件和路由命名规范 views里面代表的是你下面导航中的每一块,每个文件名 需要大写,路由命名全部小写,第一层路由就是最下面的那几个导航的名字,二级路由是在一 级路由的基础上 ...

  5. javascript 变量、常量 、 函数 声明

    声明变量: 方式一: 使用 var 定义变量,可在定义的同时赋值 或 不赋值 . 方式二: 直接使用[变量名 = 值]的形式,这会定义一个全局变量,但在严格模式下会出现引用错误.[不建议使用] 方式三 ...

  6. mysql 表这段内容替换

    update `cr_article` set `img`=replace(`img`,'http://192.168.2.10/upload','http://zouke1220.oss-cn-be ...

  7. JavaScript - String对象,字符串,String包装类型

    1. 字符串 1.1 字符串的不可变性 var str = 'abc'; str = 'hello'; // 当重新给str赋值的时候,常量'abc'不会被修改,依然在内存中 // 重新给字符串赋值, ...

  8. Python 爬取 热词并进行分类数据分析-[热词分类+目录生成]

    日期:2020.02.04 博客期:143 星期二   [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[ ...

  9. 机器学习基础系列--先验概率 后验概率 似然函数 最大似然估计(MLE) 最大后验概率(MAE) 以及贝叶斯公式的理解

    目录 机器学习基础 1. 概率和统计 2. 先验概率(由历史求因) 3. 后验概率(知果求因) 4. 似然函数(由因求果) 5. 有趣的野史--贝叶斯和似然之争-最大似然概率(MLE)-最大后验概率( ...

  10. Java通过反射实现实例化

    public static void main(String[] args) throws Exception { User user= (User) test(User.class); System ...