数据结构--图--图的数组存储表示,深度优先搜索遍历和广度优先搜索遍历

图有四种存储结构:数组,邻接表,十字链表,邻接多重表。下面以数组为存储结构来实现图的深度优先搜索遍历和广度优先搜索遍历。其中广度优先搜索遍历中有用到STL中的queue,注意头文件的包含。具体代码如下:

//图的数组(邻接矩阵)存储表示和深度优先遍历

const int MAX_VERTEX_NUM=20;  //最大顶点数
typedef enum {DG,DN,UDG,UDN} GraphKind ;//(有向图,有向网,无向图,无向网)
typedef int VRType;
typedef char InfoType;
typedef char VertexType;

typedef struct ArcCell{
    VRType adj;  //VRType是顶点关系类型,对于无权图,用1或者0表示顶点相邻与否,对于有权图,则为权值类型
    InfoType  info;//该弧相关信息指针
    ArcCell(){
        adj=0;
        info=0;
    }
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct MGraph{
    VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
    AdjMatrix arcs;  //邻接矩阵
    int vexnum,arcnum;  //图当前的顶点数和弧数
    GraphKind kind;  //图的种类标志
}MGraph;

int LocateVex(MGraph G,char v1){
    for(int i=0;i<MAX_VERTEX_NUM;++i){
        if(G.vexs[i]==v1)
        return i;
    }
    return MAX_VERTEX_NUM+1;
}

Status CreateUDN(MGraph &G){//采用数组(邻接矩阵)表示法,构建无向网
    G.kind=UDN;  //手动赋值为无向网
    int vexnumber=0,arcnumber=0;
    char info;
    cout<<"please input the vexnumber arcnumber and info:";
    cin>>vexnumber>>arcnumber>>info;
    G.vexnum=vexnumber;
    G.arcnum=arcnumber;
    for(int i=0;i<G.vexnum;++i){ //构造顶点向量
        cout<<"please input the vertex of number "<<i<<"(type char) ";
        cin>>G.vexs[i];
    }
    for(int i=0;i<G.vexnum;++i)  //初始化邻接矩阵
        for(int j=0;j<G.vexnum;++j){
            G.arcs[i][j].adj=0;
            G.arcs[i][j].info=0;
        }
    char v1,v2;
    int weight=0,i=0,j=0;
    char infomation;
    for(int k=0;k<G.arcnum;++k){  //初始化邻接矩阵
        cout<<"please input the two vertexs of the arc and it's weight "<<k+1<<" ";
        cin>>v1>>v2>>weight;
        i=LocateVex(G,v1);  j=LocateVex(G,v2);
        G.arcs[i][j].adj=weight;
        G.arcs[j][i].adj=weight;
        if(info!=48){//0的ascii码为48
            cout<<"please input infomation: ";
            cin>>infomation;
            G.arcs[i][j].info=infomation;
            G.arcs[j][i].info=infomation;
        }
    }
    return OK;
}

void DisMGraph(MGraph m){
    for(int i=0;i<m.vexnum;++i){
        for(int j=0;j<m.vexnum;++j){
            cout<<m.arcs[i][j].adj<<" ";
        }
        cout<<endl;
    }
}

//树的深度优先遍历和广度优先搜索遍历
bool visited[MAX_VERTEX_NUM] ;//访问标志数组

Status VisitFunc(MGraph G,int v){ //函数变量
    if(G.vexs[v]){
        cout<<G.vexs[v]<<" ";
        return OK;
        }
    return ERROR;
}

int FirstAdjVex(MGraph G,int v){  //返回图G中顶点V的第一个邻接点
    if(G.vexnum==0) return -1; //确定图G存在
    for(int j=0;j<G.vexnum;++j){
        if(G.arcs[v][j].adj)
            return j;
    }
    return -1;
}

int NextAdjVex(MGraph G,int v,int w){  //返回顶点v的相对与w的下一个邻接点
    if(G.vexnum==0) return -1; //确定图G存在
    for(int j=w+1;j<G.vexnum;++j){
        if(G.arcs[v][j].adj)
            return j;
    }
    return -1;
}

void DFS(MGraph G,int v){  //从第v个顶点出发,深度优先搜索遍历图G
    visited[v]=true; VisitFunc(G,v); //访问第v个结点
    for(int w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)){
        if(!visited[w]) DFS(G,w); //对v的尚未访问的邻接顶点W递归调用DFS
    }
}

void DFSTraverse(MGraph G,Status (*Visit)(MGraph G,int v)){
    //对图做深度优先遍历
    for(int v=0;v<G.vexnum;++v){  //访问标志数组初始化
        visited[v]=false;
    }
    for(int v=0;v<G.vexnum;++v){
        if(!visited[v]) DFS(G,v); //对尚未访问的结点调用DFS
    }
}

void BFSTraverse(MGraph G,Status (*Visit)(MGraph G,int v)){//广度优先搜索遍历图
    for(int v=0;v<G.vexnum;++v) visited[v]=false;
    queue<char> que;
    char tempvex=0;
    for(int v=0;v<G.vexnum;++v){
        if(!visited[v]) {
            visited[v]=true; Visit(G,v);
            que.push(G.vexs[v]);
            while(!que.empty()){
                tempvex=que.front();
                que.pop();
                for(int w=FirstAdjVex(G,tempvex);w>=0;w=NextAdjVex(G,tempvex,w)){
                    if(!visited[w]){
                        visited[w]=true;
                        Visit(G,w);
                        que.push(G.vexs[w]);
                    }
                }
            }
        }
    }
}
int main()
{
    MGraph m;
    CreateUDN(m);
    DisMGraph(m);
    cout<<"DFS result:";
    DFSTraverse(m,VisitFunc);
    cout<<endl<<"BFS result:";
    BFSTraverse(m,VisitFunc);
    return 0;
}

运行结果:

数据结构--图--图的数组存储表示,深度优先搜索遍历和广度优先搜索遍历

时间: 2024-12-23 14:59:24

数据结构--图--图的数组存储表示,深度优先搜索遍历和广度优先搜索遍历的相关文章

图的优先遍历:广度优先搜索和深度优先搜索

广度优先搜索,该算法是将已发现结点和未发现结点之间的边界,沿着其广度方向向外扩展,算法需要发现所有距离源结点 s 为 k 的所有结点之后,才会发现距离源结点 s 为 k+1 的其他结点.如果结点都被访问,算法终止. 此过程需要先构建一颗广度优先树.一开始,该树只有根结点 s (源节点).在扫描已发现结点 s 的邻接表时,每发现一个白色结点 v,就把结点染黑(这是为了记录访问的痕迹),并把它们之间的边(u, v)加入广度优先树. 该算法使用了一个具有 FIFO 特性的队列来管理已知和未知两个集合之

深度优先搜索DFS和广度优先搜索BFS

DFS简介 深度优先搜索,从起点开始按照某个原则一直往深处走,直到找到解,或者走不下去,走不下去则回溯到前一节点选择另一条路径走,直到找到解为止. BFS简介 广度优先搜索,从起点开始先搜索其相邻的节点,由此向外不断扩散,直到找到解为止. 举例解释 从1开始去寻找5 DFS: 原则:优先选择左手边 过程:1-2-3-4-6-4-5 BFS: 队列情况:1 2.5     5.3 5出来则找到 遍历图中所有点 DFS: 原则:优先选择左手边 过程:1-2-3-4-6-4-5 BFS: 队列情况:1

图的遍历之广度优先搜索(Breadth First Search)

描述 广度优先搜索算法(Breadth First Search)与树的层序遍历(level-order traversal)类似,基本思想是思想是: 从图中某顶点v出发,访问v之后,并将其访问标志置为已被访问,即visited[i]=1: 依次访问v的各个未曾访问过的邻接点: 分别从这些邻接点出发依次访问它们的邻接点,并使得"先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到: 如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为

数据结构:图的遍历--深度优先、广度优先

图的遍历:深度优先.广度优先 遍历 图的遍历是指从图中的某一顶点出发,按照一定的策略访问图中的每一个顶点.当然,每个顶点有且只能被访问一次. 在图的遍历中,深度优先和广度优先是最常使用的两种遍历方式.这两种遍历方式对无向图和有向图都是适用的,并且都是从指定的顶点开始遍历的.先看下两种遍历方式的遍历规则: 深度优先 深度优先遍历也叫深度优先搜索(Depth First Search).它的遍历规则:不断地沿着顶点的深度方向遍历.顶点的深度方向是指它的邻接点方向. 具体点,给定一图G=<V,E>,

图的遍历之 深度优先搜索和广度优先搜索

本章会先对图的深度优先搜索和广度优先搜索进行介绍,然后再给出C/C++/Java的实现. 目录 1. 深度优先搜索的图文介绍 1.1 深度优先搜索介绍 1.2 深度优先搜索图解 2. 广度优先搜索的图文介绍 2.1 广度优先搜索介绍 2.2 广度优先搜索图解 3. 搜索算法的源码 深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然

深度优先搜索与广度优先搜索

有两种常用的方法可用来搜索图:即深度优先搜索和广度优先搜索.它们最终都会到达所有连通的顶点.深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现. 深度优先搜索: 为了实现深度优先搜索,首先选择一个起始顶点并需要遵守三个规则:(1) 如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中.(2) 当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点.(3) 如果不能执行规则1和规则2,就完成了整个搜索过程. 广度优先搜索:在深度优先搜索中,算法表现得好像要尽快地远离起始点似的.相反,在广度

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

以邻接表作为存储结构的图的深度优先遍历和广度优先遍历(c++版)

一.图的存储 用邻接表法存储图,存储结构分为两部分,一部分为存储图的所有顶点的数组,另一部分为挂载在数组的每个元素后面的用来表示顶点的邻接点的链表. 1.存储顶点的结构单元为: class vnode { public: string nodename; bool visted;//进行图的遍历时用于标记图是否被访问过 node *next; vnode() { visted = false; next = NULL; } }; 链表的结构单元为: class node { public: st

数据结构之图(术语、存储结构、遍历)

1.相关术语 顶点(Vertex).弧(Arc).弧头(初始点).弧尾(终结点).边(Edge).有向图(Directed graph).无向图(Undigraph).完全图(Completed grapg).有向完全图.稀疏图(Sparse graph).稠密图(Dense graph).权(weigh).网(network).无向网.有向网.子图(Subgraph).邻接点(Adjacent).度(Degree).入度(Indegree).出度(Outdegree).路径(path).简单路