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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构C语言版 图的广度优先遍历和深度优先遍历 急急急 会查重相关的知识,希望对你有一定的参考价值。

描述给出一个无向图顶点和边的信息,输出这个无向图的深度优先遍历序列和广度优先遍历序列。从一个顶点出发如果有2个以上的顶点可以访问时,我们约定先访问编号大的那个顶点。示例输入对应的图如下图所示:输入输入的第1行有2个整数m和n。表示图g有m个顶点和n条边。第2行是m个以空格隔开的字符串,依次是图中第1个顶点的名字,第2个顶点的名字.....第m个顶点的名字。此后还有n行,每行由2个字符串构成,分别是构成图中1条边的两个顶点。我们约定不会有重边。输出输出有2行。第1行是从第1个顶点出发对图g做深度优先遍历得到的顶点序列。第2行是从第1个顶点出发对图g做广度优先遍历得到的顶点序列。样例输入8 9v1 v2 v3 v4 v5 v6 v7 v8v1 v2v1 v3v1 v6v2 v3v2 v4v3 v4v4 v6v5 v6v7 v8样例输出v1 v6 v5 v4 v3 v2 v7 v8v1 v6 v3 v2 v5 v4 v7 v8

参考技术A #include <iostream>
#include <string>
#include <queue>
using namespace std;

int FirstAdjVex(int v);
int NextAdjVex(int v, int w);
void DFS(int v); //从顶点v开始对图做深度优先遍历, v是顶点数组的下标
void BFS(int v); //从顶点v开始对图做广度优先遍历,v是顶点数组的下标
int find(string a,int n);

int visited[10]=0;
int traver[10][10]=0;
string name[10];

int main()

int n,m,i,j,k;
string a,b;
//freopen("Traver.txt","r",stdin);
cin>>n;
cin>>m;
for(i=0; i<n; i++)

cin>>a;
name[i] = a;

for(i=0; i<m;i++)
cin>>a;
cin>>b;
j = find(a,n);
k = find(b,n);
traver[j][k] = 1;
traver[k][j] = 1;

for(i=0; i<n; i++)
if(visited[i] == 0)
DFS(i);

cout<<"\\n";
for(i=0; i<n; i++)
visited[i] = 0;

for(i=0; i<n; i++)
if(visited[i] == 0)
BFS(i);

cout<<"\\n";
return 0;

//寻找函数
int find(string a,int n)
int i;
for(i=0; i<n; i++)
if(a == name[i])
return i;

return -1;

int FirstAdjVex(int v)

int i;
//从编号大的邻接点开始访问
for (i = 9; i >= 0; i--)

if (traver[v][i] == 1)
return i;

return -1;

int NextAdjVex(int v, int w)

int i;
for (i = w - 1; i >= 0; i--)

if (traver[v][i] == 1)
return i;

return -1;

void DFS(int v)

int w;
//访问顶点v(输出顶点v的名字)
cout<<name[v]<<" ";
visited[v] = 1;
//找到顶点v的第一个邻接点w
for (w = FirstAdjVex(v); w >= 0; w = NextAdjVex(v, w))

//如果w没有访问过,对顶点w做深度优先搜索
if (visited[w] == 0)
DFS(w);


void BFS(int v) //从顶点v开始对图做广度优先遍历,v是顶点数组的下标

int w, u;
queue<int> myqueue; //定义一个队列,元素是顶点的下标
//把顶点v入队
myqueue.push(v);
cout<<name[v]<<" ";
visited[v] = 1;
while (!myqueue.empty())
//当队列不为空时进入循环
//取队头元素
u = myqueue.front();
//队头元素出队
myqueue.pop();
//把u的所有邻接点入队
w = FirstAdjVex(u);
while (w >= 0)

if (visited[w] == 0)

//访问w
cout<<name[w]<<" ";
visited[w] = 1;
//w入队
myqueue.push(w);

w = NextAdjVex(u, w);


本回答被提问者和网友采纳

图的深度优先遍历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语言程序

c语言图的遍历,邻接表存储,深度,广度优先遍历

数据结构—无向图创建邻接矩阵深度优先遍历和广度优先遍历(C语言版)

C语言实现图的广度优先搜索遍历算法

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

图的遍历和生成树求解实现 (c语言版)