zoukankan      html  css  js  c++  java
  • 复杂数据结构(四)图

    图的遍历

    广度优先遍历类似于树的按层次遍历,具体过程如下:
    (1)从数组中选择一个未被访问的顶点Vi,将其标记为已访问。
    (2)接着依次访问Vi的所有未被访问的邻接点,并标记为已被访问过。
    (3)从这些邻接点出发进行广度优先遍历,直至图中所有和Vi有路径相通的顶点都被访问过。
    (4)重复步骤(1)至步骤(3)的操作,直至所有顶点都被访问过。

    图(f)采用广度优先搜索遍历以V0为出发点的顶点序列为:V0,V1,V3,V4,V2,V6,V8,V5,V7

    深度优先遍历方法类似于树的先序遍历,具体过程如下:
    (1)从数组中选择一个未被访的顶点Vi,将其标记为已访问。
    (2)接着从Vi的一个未被访问过的邻接点出发进行深度优先遍历。
    (3)重复步骤(2),直至图中所有和Vi有路径相通的顶点都被访问过。
    (4)重复步骤(1)至步骤(3)的操作,直至所有顶点都被访问过。

    ds59

    红色数字代表遍历的先后顺序,所以图(e)无向图的深度优先遍历的顶点访问序列为:V0,V1,V2,V5,V4,V6,V3,V7,V8

    程序编写<GraphTrav>:

    #include <stdio.h>
    #include "AdjMatrixGraph.c"//之前邻接矩阵保存图法时编写的
    #define QUEUE_MAXSIZE 30 //队列的最大容量 
    typedef struct
    {
        int Data[QUEUE_MAXSIZE]; //数据域
        int head; //队头指针
        int tail; //队尾指针
    }SeqQueue; //队列结构
    //队列操作函数 
    void QueueInit(SeqQueue *q); //初始化一个队列   
    int QueueIsEmpty(SeqQueue q); //判断队列是否空   
    int QueueIn(SeqQueue *q,int n); //将一个元素入队列   
    int QueueOut(SeqQueue *q,int *ch); //将一个元素出队列  
    
    //图操作函数 
    void DFSTraverse(MatrixGraph *G); //深度优先遍历 
    void BFSTraverse(MatrixGraph *G); //广度优先遍历 
    void DFSM(MatrixGraph *G,int i);
    void BFSM(MatrixGraph *G,int i);
    
    void QueueInit(SeqQueue *Q)    //队列初始化  
    {
        Q->head=Q->tail=0;
    }
    int QueueIsEmpty(SeqQueue Q)   //判断队列是否已空,若空返回1,否则返回0 
    {
        return Q.head==Q.tail; 
    }
    int QueueIn(SeqQueue *Q,int ch)   //入队列,成功返回1,失败返回0   
    {
        if((Q->tail+1) % QUEUE_MAXSIZE ==Q->head) //若队列已满 
            return 0;  //返回错误; 
        Q->Data[Q->tail]=ch; //将数据ch入队列 
        Q->tail=(Q->tail+1) % QUEUE_MAXSIZE; //调整队尾指针 
        return 1; //成功,返回1 
    }
    int QueueOut(SeqQueue *Q,int *ch)   //出队列,成功返回1,并用ch返回该元素值,失败返回0  
    {
        if(Q->head==Q->tail) //若队列为空 
            return 0; //返回错误 
        *ch=Q->Data[Q->head]; //返回队首元素 
        Q->head=(Q->head+1) % QUEUE_MAXSIZE; //调整队首指针 
        return 1; //成功出队列,返回1   
    }   
    
    void DFSTraverse(MatrixGraph *G) //深度优先遍历 
    {
        int i;
        for(i=0;i<G->VertexNum;i++) //清除各顶点遍历标志 
            G->isTrav[i]=0;
        printf("深度优先遍历结点:"); 
        for(i=0;i<G->VertexNum;i++)
            if(!G->isTrav[i]) //若该点未遍历 
                DFSM(G,i); //调用函数遍历 
        printf("
    "); 
    
    }
    void DFSM(MatrixGraph *G,int i) //从第i个结点开始,深度遍历图 
    {
        int j;
        G->isTrav[i]=1; //标记该顶点已处理过 
        printf("->%c",G->Vertex[i]);//输出结点数据 
    //    printf("%d->",i); //输出结点序号 
    
        //添加处理节点的操作 
        for(j=0;j<G->VertexNum;j++)
            if(G->Edges[i][j]!=MAXVALUE && !G->isTrav[i])
                DFSM(G,j); //递归进行遍历 
    }
    void BFSTraverse(MatrixGraph *G) //广度优先 
    {
        int i;
        for (i=0;i<G->VertexNum;i++) //清除各顶点遍历标志 
            G->isTrav[i]=0;
        printf("广度优先遍历结点:"); 
        for (i=0;i<G->VertexNum;i++)
            if (!G->isTrav[i])
                BFSM(G,i);
        printf("
    ");
    }
    void BFSM(MatrixGraph *G,int k) //广度优先遍历 
    {
        int i,j;
        SeqQueue Q; //创建循环队列 
        QueueInit(&Q); //初始化循环队列 
    
        G->isTrav[k]=1; //标记该顶点 
        printf("->%c",G->Vertex[k]);  //输出第一个顶点 
    
        //添加处理节点的操作 
        QueueIn(&Q,k); //入队列 
        while (!QueueIsEmpty(Q)) //队列不为空 
        {
            QueueOut(&Q,&i); //出队列 
            for (j=0;j<G->VertexNum;j++)
                if(G->Edges[i][j]!=MAXVALUE && !G->isTrav[j])
                {
                    printf("->%c",G->Vertex[j]);
                    G->isTrav[j]=1;  //标记该顶点
                    //处理顶点 
                    QueueIn(&Q,j); //出队列 
                }
        }
    }

    事件:

    #include <stdio.h>
    #include "GraphTrav.c"
    int main()
    {
        MatrixGraph G; //定义保存邻接表结构的图 
        int path[VERTEX_MAX];
        int i,j,s,t;
        char select;
        do
        {
            printf("输入生成图的类型(0:无向图,1:有向图):");
            scanf("%d",&G.GraphType); //图的种类
            printf("输入图的顶点数量和边数量:");
            scanf("%d,%d",&G.VertexNum,&G.EdgeNum); //输入图顶点数和边数 
            for(i=0;i<G.VertexNum;i++)  //清空矩阵 
                for(j=0;j<G.VertexNum;j++)
                    G.Edges[i][j]=MAXVALUE; //设置矩阵中各元素的值为0         
            CreateMatrixGraph(&G); //生成邻接表结构的图
            printf("邻接矩阵数据如下:
    ");
            OutMatrix(&G); //输出邻接矩阵             
            DFSTraverse(&G); //深度优先搜索遍历图 
            BFSTraverse(&G); //广度优先搜索遍历图
            printf("图遍历完毕,继续进行吗?(Y/N)"); 
            scanf(" %c",&select);
        }while(select!='N' && select!='n');    
        getch();
        return 0;
    }

    结果:

    image

  • 相关阅读:
    2019年8月下旬
    2019年8月上旬
    2019年7月 vue专题
    2019年7月上
    mysql安装 demo [linux centos7] [5.7.26]
    记一个日志冲突——管中窥豹[java混乱的日志体系]
    Mybatis-Generator demo
    dubbo doc入门文档
    springBoot+mysql+mybatis demo [基本配置] [遇到的问题]
    nginx安装demo
  • 原文地址:https://www.cnblogs.com/moguwang/p/5287617.html
Copyright © 2011-2022 走看看