关于数据结构的深度优先遍历和广度优先遍历以及最小生成树 第四大题的第一题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于数据结构的深度优先遍历和广度优先遍历以及最小生成树 第四大题的第一题相关的知识,希望对你有一定的参考价值。

参考技术A 首先看一下深度优先和广度优先怎么遍历:
深度优先遍历从某个顶点出发,首先访问这个顶点,然后找出刚访问这个结点的第一个未被访问的邻结点,然后再以此邻结点为顶点,继续找它的下一个新的顶点进行访问,重复此步骤,直到所有结点都被访问完为止。
广度优先遍历从某个顶点出发,首先访问这个顶点,然后找出这个结点的所有未被访问的邻接点,访问完后再访问这些结点中第一个邻接点的所有结点,重复此方法,直到所有结点都被访问完为止。
在看题目,其要求按顺时针方向:
深度优先序列:V1 V2 V3 V5 V4
广度优先序列:V1 V2 V4 V3 V5
最小生成树,有两种方法,prim和kruskal算法。
这题最小生成树如下:
[(V4,V5),(V1,V4),(V2,V4),(V5,V3)],其中(V4,V5)表示V4和V5点之间连线。如下图类似(这里简单表示一下)。
V1 V2 V3
\ / /
V4----V5

图的深度优先遍历DFS和广度优先遍历BFS(邻接矩阵存储)超详细完整代码进阶版


前言

 关于图的深度优先遍历(DFS)和广度优先遍历(BFS)的基本概念以及图的邻接矩阵存储,可参考文章图的深度优先遍历DFS和广度优先遍历BFS(邻接矩阵存储)超详细完整代码简单版

 在上篇文章中,我们已经介绍了图的深度优先遍历和广度优先遍历的基本概念及简单实现(顶点值与数组下标对应),那么对于任意类型的顶点的图,该如何实现对其的深度优先遍历和广度优先遍历呢?在下面的内容中将会给出答案。

 下面从零开始,一步一步实现图的深度优先遍历和广度优先遍历。

邻接矩阵存储的结构定义

首先,给出邻接矩阵存储的结构定义:

#define maxvertexnum 30  //最大顶点个数
typedef char VertexType; //顶点的类型
typedef int EdgeType; 

typedef struct{
    VertexType Vertex[maxvertexnum];  //顶点表
    EdgeType Edge[maxvertexnum][maxvertexnum];  //边表
    int vexnum, edgenum; //顶点数和边数
}MGraph;

构建一个无权有向图(邻接矩阵存储)

图的顶点保存在数组v[n]中,图的边(顶点对)保存在数组edge[e][2]中。

//返回顶点的存储下标,将顶点值转换为顶点号
int getPos(MGraph G, VertexType v){
    int i;
    for(i=0; i<G.vexnum; i++){
        if(G.Vertex[i] == v){
            break;
        }
    }
    return i;
}
//无权有向图的邻接矩阵存储
void CreateMGraph(MGraph &G, VertexType v[], VertexType edge[][2], int n, int e){
    //v[n]存放顶点,edge[e][2]存放有向边
    //初始化
    G.vexnum = n; //顶点数
    G.edgenum = e;  //边数
    for(int i=0; i<G.vexnum; i++){
        G.Vertex[i] = v[i];
        for(int k=0; k<G.vexnum; k++){
            G.Edge[i][k] = 0; //邻接矩阵初始化全为0
        }
    }
    //根据输入边形成邻接矩阵
    for(int i=0; i<G.edgenum; i++){
        int j = getPos(G, edge[i][0]); //顶点edge[i][0]的存储位置
        int k = getPos(G, edge[i][1]); //顶点edge[i][1]的存储位置
        G.Edge[j][k] = 1;
    }
}

查找顶点v的第一个邻接点FirstNeighbor

//第一个邻接点
VertexType FirstNeighbor(MGraph G, VertexType v){
    int i = getPos(G, v); //找到顶点v的存储位置
    for(int j=0; j<G.vexnum; j++){
        if(G.Edge[i][j] >0) //找到第一个大于0的边
            return G.Vertex[j];
    }
    return '0'; //不存在则返回'0'
}

查找顶点v的邻接点w的下一个邻接点NextNeighbor

//下一个邻接点
VertexType NextNeighbor(MGraph G, VertexType v, VertexType w){
    int i = getPos(G, v);
    int j = getPos(G, w);
    for(int k=j+1; k<G.vexnum; k++){ //从w开始找,找到w后面第一个大于0的边
        if(G.Edge[i][k] >0)
            return G.Vertex[k];
    }
    return '0'; //不存在则返回'0'
}

深度优先遍历DFS

int visited[maxvertexnum]; //访问标记数组
//深度优先遍历
void DFS(MGraph G,VertexType v){
    cout<<v;
    visited[getPos(G,v)] = 1;
    for(VertexType w=FirstNeighbor(G,v); w!='0'; w=NextNeighbor(G,v,w)){ 
        if(!visited[getPos(G,w)])
            DFS(G,w);
    }
}
void DFSTraverse(MGraph G){
    for(int i=0; i<G.vexnum; i++){
        visited[i] = 0; //初始化标记数组
    }
    for(int i=0; i<G.vexnum; i++){
        if(!visited[i]){
            DFS(G,G.Vertex[i]);
        }
    }
}

广度优先遍历BFS

广度优先遍历需要借助队列暂存邻接顶点

//广度优先遍历
void BFS(MGraph G, VertexType v){
    queue<VertexType> vex; //借助队列存储邻接顶点
    cout<<v;
    visited[getPos(G,v)] = 1;
    vex.push(v);
    while(!vex.empty()){
        VertexType u = vex.front(); //获取队首元素
        vex.pop(); //出队
        for(VertexType w=FirstNeighbor(G,v); w!='0'; w=NextNeighbor(G,v,w)){
            if(!visited[getPos(G,w)]){
                cout<<w;
                visited[getPos(G,w)] = 1;
                vex.push(w); //入队
            }
        }
    }
}
void BFSTraverse(MGraph G){
    for(int i=0; i<G.vexnum; i++){
        visited[i] = 0; //初始化标记数组
    }
    for(int i=0; i<G.vexnum; i++){
        if(!visited[i]){
            BFS(G, G.Vertex[i]);
        }
    }
}

主函数

int main(){
    MGraph G;
    int n,e;
    cin>>n>>e;
    VertexType v[n];
    VertexType edge[e][2];
    for(int i=0; i<n; i++){
        cin>>v[i];
    }
    for(int i=0; i<e; i++){
        cin>>edge[i][0]>>edge[i][1];
    }
    CreateMGraph(G, v, edge, n, e);
    DFSTraverse(G);
    cout<<endl;
    BFSTraverse(G);
    return 0;
}

运行结果

以上是关于关于数据结构的深度优先遍历和广度优先遍历以及最小生成树 第四大题的第一题的主要内容,如果未能解决你的问题,请参考以下文章

二叉树遍历(前序中序后序层次深度优先广度优先遍历)

图的深度/广度优先遍历C语言程序

邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)

邻接表c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)

关于广度优先遍历,你知道多少?

数据结构C语言版 图的广度优先遍历和深度优先遍历 急急急 会查重