zoukankan      html  css  js  c++  java
  • 【转】邻接表的DFS、BFS、两结点的全部简单路径

    晚上看视频的时候一不小心把浏览器关了,所以丢失了原文链接...

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define MAX_VERTEX_NUM 20
    #define OVERFLOW 0
    #define OK 1
    #define TRUE 1  
    #define FALSE 0 
    typedef  int   Status  ;
    typedef  char VertexType;
    typedef  int  QElemType;
    typedef struct ArcNode
    {
         int adjvex;                            //邻接点域,存储该邻点顶点对应的下标
         struct ArcNode *nextarc;             //邻节点
         int weight;                        //权值
    }ArcNode;
    /*邻接表结构*/
    typedef struct VNode
    {
         VertexType data;                   //顶点对应的值
         ArcNode  *firstarc;            //边表头指针指向邻顶点
    }VNode,AdjList[MAX_VERTEX_NUM];
     
    typedef struct
    {
         AdjList  vertices;  
         int vexnum,arcnum;                //顶点数,边数
    }ALGraph;
     
    /*队列结构*/
     
    typedef struct QNode     
    {  
        QElemType data;  
        struct QNode *next;  
    }QNode,*QueuePtr;   
     
    typedef struct {
        int    data[MAX_VERTEX_NUM];
        int    front, rear;
    }Queue;
     
    //队列顺序表的相关操作
    //初始化
    void InitQueue(Queue *Q)
    {
        Q->front = Q->rear = 0;
    }
     
    //入队
    void EnQueue(Queue *Q, int e)
    {
        if ((Q->rear+1)%MAX_VERTEX_NUM == Q->front)
            return ;
        Q->data[Q->rear] = e;
        Q->rear = (Q->rear+1)%MAX_VERTEX_NUM;
    }
     
    //判空
    int QueueEmpty(Queue *Q)
    {
        if (Q->front == Q->rear)
            return 1;
        else
            return 0;
    }
     
    //出队
    void DeQueue(Queue *Q, int *e)
    {
        if (Q->front == Q->rear)
            return ;
        
        *e = Q->data[Q->front];
        Q->front = (Q->front+1)%MAX_VERTEX_NUM;
    }
     
     
    void CreateALGraph(ALGraph *G)    //构建图
    {
         ArcNode *p;
         int i,j,k;
         printf("输入顶点与边的数目:
    ");
         scanf("%d%d",&G->vexnum,&G->arcnum);
         getchar();
         printf("输入顶点值:
    ");
        for(i=1;i<=G->vexnum;i++)
        {
              scanf("%c",&G->vertices[i].data);
              getchar();
              G->vertices[i].firstarc=NULL;
        }
        //建立边表
        printf("输入邻接表对应的下标:(从1开始)
    ");
        for(k=1;k<=G->arcnum;k++)
        {
              scanf("%d%d",&i,&j);   //边对应的两个顶点下标并将俩顶点联系起来
              p = (ArcNode *)malloc(sizeof(ArcNode));
              p->adjvex = j;
              p->nextarc = G->vertices[i].firstarc;
              G->vertices[i].firstarc = p;
              /*有向图只要上部分即可*/ 
              p  =  (ArcNode*)malloc(sizeof(ArcNode));
              p->adjvex = i;
              p->nextarc = G->vertices[j].firstarc;
              G->vertices[j].firstarc = p;
        }
    }
     
    int visited[MAX_VERTEX_NUM];        //记录是否被访问
    /*邻接表的深度遍历*/ 
    void DFS(ALGraph G,int i)
    {
         int j;
         ArcNode *p;
         visited[i]=1;     //将要访问的顶点置为1
         printf("%c ",G.vertices[i].data); //输出各顶点
         for(p = G.vertices[i].firstarc;p!=NULL;p=p->nextarc)
         {
                j = p->adjvex;
              if(visited[j]==0) //深度探索
                DFS(G,j);
         }
    }
     
    void Is_connected(ALGraph G)
    {
         int i;
         int count = 0;
         for(i=1;i<=G.vexnum;i++)
              visited[i]=0;      //初始化0,未被访问
         for(i=1;i<=G.vexnum;i++)
         {
              if(!visited[i])
              {
                   printf("
    ");
                   DFS(G,i);
                   count++;  //记录连通图个数(>1)则整体是个非连通图
              }
         }
         printf("
    连通图个数为:%d
    ",count);
    }
     
    /*邻接表的广度遍历*/
    void BFSTraverse(ALGraph g)
    {
        ArcNode *p;
           Queue Q;   
           InitQueue(&Q);  
        for(int i = 1; i <= g.vexnum; i++)
        {
            visited[i] = 0;
        }  
        for(int j = 1; j<=g.vexnum; j++)
        {
            if(!visited[j])
            {
                printf("%c ", g.vertices[j].data);   //打印顶点,也可以其他操作
                visited[j] = 1;
                EnQueue(&Q,j);
                while(!QueueEmpty(&Q))
                {
                    int m;
                    DeQueue(&Q,&m);                        //访问点出队列 
                    p = g.vertices[m].firstarc;     //找到当前顶点边表链表头指针
                    while(p)                 
                    {
                        if(!visited[p->adjvex])
                        {
                            printf("%c ", g.vertices[p->adjvex].data);
                            visited[p->adjvex] = 1;
                            EnQueue(&Q, p->adjvex);
                        }
                            p = p->nextarc;
                    }
                }
            }
        }
    }
     
    int flag = 0;      //标志探寻点置0
    int top = 0;
    char path[MAX_VERTEX_NUM];
     
    /*连通图的简单路径(类dfs) */
    void pathdfs(ALGraph G,int i,int j)
    {
        ArcNode *p;
        int s,w;
        visited[i]=1;           //将顶点i加入当前路径
        path[++top] = G.vertices[i].data;
        if(!flag && path[top]==G.vertices[j].data)
            flag = 1;   //存在顶点i到顶点j的路径
        if(flag)       //找到
        {
        //输出当前路径上所有顶点
            printf("
    ");
        for(s=1;s<=top;s++)
            printf("%c	",path[s]);
            flag = 0;
        }
        else
        for(p=G.vertices[i].firstarc;p;p=p->nextarc)
        {
            w = p->adjvex;
            if(!visited[w])
            pathdfs(G,w,j);
        }
            visited[i]=0;         //每当顶点i回溯时,把visited[i]置为0,下次可通过顶点i寻找其他可能到达j的路径
            top--;               //删除顶点i
     
    }
     
    int main()
    {
            ALGraph G;
            CreateALGraph(&G);
            printf("-------------------
    ");
            printf("简单路径为:");
            pathdfs(G,1,3);
            printf("
    连通图的深度遍历为:");
            Is_connected(G);
            printf("
    连通图的广度遍历为:");
            BFSTraverse(G);
            return 0;
    }
    /*
    样例图:
           2
          /  
        /      
       1--------3
       |        |
       |        |
       5--------4
    样例输入: 5 6 1 2 3 4 5 1 2 1 3 1 5 2 3 3 4 4 5
    */

  • 相关阅读:
    es从aws迁移阿里云问题总结
    MySQL & Canal流程&架构梳理
    这么优雅的Java ORM没见过吧!
    Five86-1靶机渗透实战
    从信息泄露到域控
    禁用浏览器在触摸屏上双指缩放的功能
    使用java动态字节码技术简单实现arthas的trace功能。
    apisix网关-构建docker镜像构建及插件化开发
    query扩展方法汇总
    为什么.NET Standard 仍然有意义?
  • 原文地址:https://www.cnblogs.com/exciting/p/10112662.html
Copyright © 2011-2022 走看看