邻接矩阵的深度优先遍历

摘要:对《大话数据结构》P240——邻接矩阵的深度优先遍历,进行了自己的理解并完善了代码。Qt Creator测试通过。

举个简单的无序图例子,为了节省时间传手稿。

首先用邻接矩阵的存储结构创建该图,再进行深度优先遍历。代码和解释如下:

#include <iostream>
#include <stdlib.h>
using namespace std;

typedef struct//图的邻接矩阵存储结构
{
    char vexs[5];
    int arc[5][5];
    int numVertexes,numEdges;
}MGraph;

MGraph *CreateMGraph(MGraph *G)//图的创建
{
    G=(MGraph*)malloc(sizeof(MGraph));
    int i,j,k;
    cout<<"input numVertexes and numEdges"<<endl;
    cin>>G->numVertexes>>G->numEdges;//输入5 8
        cout<<"input numVertexes"<<endl;
    for(i=0;i<G->numVertexes;i++)
        cin>>G->vexs[i];//每次循环依次输入A B C D E
        for(i=0;i<G->numVertexes;i++)
        for(j=0;j<G->numVertexes;j++)
            G->arc[i][j]=0;
    for(k=0;k<G->numEdges;k++)
    {
        cout<<"input vi and vj"<<endl;
        cin>>i>>j;//每次循环依次输入0 1,0 2,0 3,0 4,1 2,1 4,2 3,3 4
                G->arc[i][j]=1;
        G->arc[j][i]=1;
    }
    return G;
}

int visited[5];//设置为全局变量,DFS和DFSTraverse函数都有用到

//以下标为i的顶点vexs[i]开始访问,进行一次深度优先递归,对连通图,可以访问到所有的顶点
void DFS(MGraph *G,int i)
{
    visited[i]=1;//访问过的顶点标记为1
        cout<<G->vexs[i]<<" ";//递归之前需要打印当前访问的顶点
        for(int j=0;j<G->numVertexes;j++)//从第0个顶点开始判断,直到最后一个顶点
        if((G->arc[i][j]==1)&&(!visited[j]))//若顶点vexs[j]与顶点vexs[i]相连,并且vexs[j]没有访问过
        DFS(G,j);//那就访问vexs[j]
    //cout<<G->vexs[i]<<" ";//如果写在最后,则逆序输出,可以将上面的cout注释掉试一下
}

//邻接矩阵的深度遍历
void DFSTraverse(MGraph *G)
{
    for(int i=0;i<G->numVertexes;i++)
        visited[i]=0;//初始化所有顶点都是未访问过
        for(int i=0;i<G->numVertexes;i++)
        if(!visited[i]) DFS(G,i);
    //从vexs[0]开始进行深度优先递归,若是连通图,只会执行一次DFS(G,0)
    //因为深度优先递归后每个visited[i]都是1,不会再执行if了
    //若是非连通图,可能会执行到DFS(G,1),DFS(G,2),DFS(G,3),DFS(G,4)
}

int main()
{
    MGraph *p=NULL;
    p=CreateMGraph(p);//这里也可以用二级指针,参考二叉树为什么用二级指针作为参数那篇博客
        cout<<p->vexs[0]<<" "<<p->vexs[1]<<" "<<p->vexs[2]<<" "<<p->vexs[3]<<" "<<p->vexs[4]<<endl;
    cout<<p->arc[0][1]<<" "<<p->arc[0][2]<<" "<<p->arc[0][3]<<" "<<p->arc[0][4]<<" "<<p->arc[1][2]<<" "<<p->arc[1][4]<<" "<<p->arc[2][3]<<" "<<p->arc[3][4]<<endl;
    //验证创建是否正确
    //DFS(p,2);//举个例子,若从下标2开始,执行一次DFS(G,2),输出的遍历顺序是CABED
        DFSTraverse(p);//输出的遍历顺序是ABCDE
}

1、先理解void DFS(MGraph *G,int i)这个函数,假设从下标2开始,执行一次DFS(G,2),那么遍历结果是CABED

main函数中用DFS(p,2);把DFSTraverse(p);注释掉。

由于是连通图,执行一次DFS(G,2)即可遍历全部顶点。

2、考虑问题得全面,如果是非连通图,执行一次DFS(G,2),会有顶点没有被遍历到。解决办法是依次执行DFS(G,0),DFS(G,1),DFS(G,2),DFS(G,3),DFS(G,4)即可。用visited[i]对是否访问过该顶点标记,防止不必要的循环。

main函数中用DFSTraverse(p);把DFS(p,2);注释掉。

时间: 2024-10-12 11:04:26

邻接矩阵的深度优先遍历的相关文章

邻接矩阵的深度优先遍历(java版)

这是一个有向边带权的图 顶点数组:[v0, v1, v2, v3, v4] 边数组: v0 v1 v2 v3 v4 v0 6 v1 9 3 v2 2 5 v3 1 v4 package com.datastruct; import java.util.Scanner; public class MGraph { //定义图结构,使用邻接矩阵存储 private static class Graph{ final int MAXVEX = 10;//最大顶点数 final int INFINITY

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

matrix.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <limits.h> #include "aqueue.h" #define MAX_VALUE INT_MAX #define MAX_NUM 100 typedef char node_type; typedef struct matrix { node_type vertex[M

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

graph.c #include <stdio.h> #include <stdlib.h> #include <limits.h> #include "aqueue.h" #define MAX_NUM 100 typedef char node_type; typedef struct arc_node { int pos; int distance; struct arc_node * next; } Arc_node;//保存Node节点的相

邻接表的深度优先遍历

转载请注明出处http://www.cnblogs.com/hslzju 对<大话数据结构>P241——邻接表的深度优先遍历,进行了自己的理解并完善了代码. 邻接矩阵的深度优先遍历见http://www.cnblogs.com/hslzju/p/5399249.html 举个简单的无序图例子,为了节省时间传手稿. 首先用邻接表的存储结构创建该图,再进行深度优先遍历.代码和解释如下(Qt Creator测试通过): 1 #include <iostream> 2 #include &

C++实现图的邻接矩阵的创建以及其深度优先遍历和广度优先遍历

#include<iostream> using namespace std; typedef char vertextype; typedef int edgetype; #define maxvex 100 #define infinity 1000 #include<queue> int visited[100]; class MGraph{ public: vertextype vexs[maxvex]; edgetype arc[maxvex][maxvex]; int

存储结构与邻接矩阵,深度优先和广度优先遍历及Java实现

如果看完本篇博客任有不明白的地方,可以去看一下<大话数据结构>的7.4以及7.5,讲得比较易懂,不过是用C实现 下面内容来自segmentfault 存储结构 要存储一个图,我们知道图既有结点,又有边,对于有权图来说,每条边上还带有权值.常用的图的存储结构主要有以下二种: 邻接矩阵 邻接表 邻接矩阵 我们知道,要表示结点,我们可以用一个一维数组来表示,然而对于结点和结点之间的关系,则无法简单地用一维数组来表示了,我们可以用二维数组来表示,也就是一个矩阵形式的表示方法. 我们假设A是这个二维数组

邻接矩阵 + 深度优先遍历

1 /** 2 知识点:(有向图) 3 强连通图的邻接矩阵存储图: 4 强连通图的深度优先遍历(递归方式实现) 5 */ 6 #include <stdio.h> 7 #include <string.h> 8 #define N 5 9 #define ARC 10 10 int visit[ARC]; 11 typedef struct { 12 char vex[ARC][N];///顶点 13 int arc[ARC][ARC]; 14 int numv,nume;///顶

基于邻接矩阵存储的图的深度优先遍历和广度优先遍历

图的存储结构相比较线性表与树来说就复杂很多,对于线性表来说,是一对一的关系,所以用数组或者链表均可简单存放.树结构是一对多的关系,所以我们要将数组和链表的特性结合在一起才能更好的存放. 那么我们的图,是多对多的情况,另外图上的任何一个顶点都可以被看作是第一个顶点,任一顶点的邻接点之间也不存在次序关系. 仔细观察以下几张图,然后深刻领悟一下: 因为任意两个顶点之间都可能存在联系,因此无法以数据元素在内存中的物理位置来表示元素之间的关系(内存物理位置是线性的,图的元素关系是平面的). 如果用多重链表

PTA 邻接矩阵存储图的深度优先遍历

6-1 邻接矩阵存储图的深度优先遍历(20 分) 试实现邻接矩阵存储图的深度优先遍历. 函数接口定义: void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) ); 其中MGraph是邻接矩阵存储的图,定义如下: typedef struct GNode *PtrToGNode; struct GNode{ int Nv; /* 顶点数 */ int Ne; /* 边数 */ WeightType G[MaxVertexNum][MaxVe