题目地址:https://pta.patest.cn/pta/test/558/exam/4/question/9495

由于边数E<(n*(n-1))/2 所以我选用了邻接表实现,优先队列用循环队列实现;

DFS基本思路:

  1:选择一个点,标志已经访问过;

  2:判断这个点的其他邻接点(访问顺序按题目是从小到大)是否访问过,来选择下一个点;

  3:重复第2点直到全部点已经访问过。

伪代码如下

DFS( Vertex v )
{
    Visit( V );
    Visited[V] = true; 

    foreach(  v->neighbor )
        if ( Visited[v->neighbor ] == false )
            DFS(v->neighbor );
}

BFS基本思路:

  1:选择一个点入队,并访问这个点,标志已经访问过;

  2:出队,将这个点未访问过的全部邻点访问并入队;

  3:重复第二点直到队列为空;

伪代码如下

BFS ( Vertex v )
{ 

    Visit( v );
    Visited[v] = true;
    EnQueue(Q, v); 

    while ( !IsEmpty(Q) )
    {
        w = DeQueue(Q);
        foreach ( w->neighor )
            if ( Visited[w->neighor] == false )
            {
                Visit( w->neighor );
                Visited[w->neighor] = true;
                EnQueue(Q, w->neighor);
            }
    }
}        

具体代码

 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
 #include <dos.h>

 #define MaxVertexNum 10

 typedef int ElementType;
 typedef int Position;

 typedef struct QNode {
     ElementType *Data;     /* 存储元素的数组 */
     Position Front, Rear;  /* 队列的头、尾指针 */
     int MaxSize;           /* 队列最大容量 */
 }QNode, *Queue;

 typedef struct ENode
 {
     int ivex;            //该边指向的顶点位置
     struct ENode * next;
 }ENode, *PENode;

 typedef int VertexType; 

 typedef struct VNode
 {
     VertexType data;
     ENode * first_edge;
 }VNode;

 typedef struct LGraph
 {
     int vexnum;            //图的顶点数目
     int edgnum;            //图的边的数目
     VNode * vexs;       //存放顶点的数组
 }LGraph;

 bool TAG;                   //用于输出格式
 bool visited[MaxVertexNum];

 LGraph * LGraph_new();
 void LGraph_destroy(LGraph * G);
 void LGraph_insert(ENode ** head, int ivex);
 void ResetVisit();
 void DFS(LGraph * G, int vex);
 void BFS(LGraph * G, int vex);
 void ListComponents(LGraph * G, void (*func)(LGraph * G, int vex));

 //优先队列的基本操作
 Queue CreateQueue( int MaxSize );
 bool IsFull( Queue Q );
 bool AddQ( Queue Q, ElementType X );
 bool IsEmpty( Queue Q );
 ElementType DeleteQ( Queue Q );

 int main()
 {
     LGraph * G = LGraph_new();
     ResetVisit();
     ListComponents(G, DFS);
     ResetVisit();
     ListComponents(G, BFS);
     system("pause");
     ;
 }

 void ListComponents(LGraph * G, void (*func)(LGraph * G, int vex))
 {
     int i;
     ; i < G->vexnum; ++i )
     {
         if (visited[i] == false)
         {
             (*func)(G, i);
             printf("}\n");
             TAG = false;
         }
     }
 }

 LGraph * LGraph_new()
 {

     LGraph * G = (LGraph *)malloc(sizeof(LGraph));
     scanf("%d %d", &G->vexnum, &G->edgnum);
     G->vexs = (VNode *)malloc(G->vexnum * sizeof(VNode));
     int i, v1, v2;
     ; i < G->vexnum; ++i )
     {
         G->vexs[i].data = i;
         G->vexs[i].first_edge = NULL;
     }
     ; i < G->edgnum; ++i )
     {
         scanf("%d %d", &v1, &v2);
         //由于顶点信息就是顶点坐标
         LGraph_insert(&G->vexs[v1].first_edge, v2);
         LGraph_insert(&G->vexs[v2].first_edge, v1);
     }
     return G;
 }

 void ResetVisit()
 {
     TAG = false;
     memset(visited, false, sizeof(visited));
 }

 void LGraph_insert(ENode ** head, int ivex)
 {
     ENode *pnew, *p1, *p2;
     pnew = (ENode *)malloc(sizeof(ENode));
     pnew->ivex = ivex;
     if ( *head == NULL )
     {
         *head = pnew;

         pnew->next = NULL;
     }
     else
     {
         if ( (*head)->ivex > ivex ) //没头结点的麻烦
         {
             pnew->next = *head;
             *head = pnew;
         }
         else
         {
             for (p1 = *head,    p2 = p1->next; p2 != NULL ; p1 = p2, p2 = p1->next )
             {
                 if ( p2->ivex > ivex )
                     break;
             }
             pnew->next = p2;
             p1->next = pnew;
         }
     }
 }

 void DFS(LGraph * G, int vex)
 {
     if (TAG == false)
     {
         TAG = true;
         printf("{ ");
     }
     printf("%d ", vex);
     visited[vex] = true;
     ENode * temp = G->vexs[vex].first_edge;
     while( temp != NULL )
     {
         if (visited[temp->ivex] == false)
         {
              DFS(G, temp->ivex);
         }
         temp = temp->next;
     }
 }
 void BFS(LGraph * G, int vex)
 {
     Queue Q = CreateQueue(G->vexnum);
     if (TAG == false)
     {
         TAG = true;
         printf("{ ");
     }
     printf("%d ", vex);
     visited[vex] = true;
     AddQ(Q, vex);
     while (!IsEmpty(Q))
     {
         vex = DeleteQ(Q);
         ENode * temp = G->vexs[vex].first_edge;
         while (temp != NULL)
         {
             if ( visited[temp->ivex] == false )
             {
                 printf("%d ",temp->ivex);
                 visited[temp->ivex] = true;
                 AddQ(Q, temp->ivex);
             }
             temp = temp->next;
         }
     }
     free(Q->Data);
     free(Q);
 }

 //队列基本操作
 Queue CreateQueue( int MaxSize )
 {
     Queue Q = (Queue)malloc(sizeof(struct QNode));
     Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
     Q->Front = Q->Rear = ;
     Q->MaxSize = MaxSize;
     return Q;
 }

 bool IsFull( Queue Q )
 {
     )%Q->MaxSize == Q->Front);
 }

 bool AddQ( Queue Q, ElementType X )
 {
     if ( IsFull(Q) ) {
         printf("队列满");
         return false;
     }
     else {
         Q->Rear = (Q->Rear+)%Q->MaxSize;
         Q->Data[Q->Rear] = X;
         return true;
     }
 }

 bool IsEmpty( Queue Q )
 {
     return (Q->Front == Q->Rear);
 }

 ElementType DeleteQ( Queue Q )
 {
     if ( IsEmpty(Q) ) {
         printf("队列空");
         ;
     }
     else  {
         Q->Front =(Q->Front+)%Q->MaxSize;
         return  Q->Data[Q->Front];
     }
 }

06-图1 列出连通集 (25分)(C语言邻接表实现)的更多相关文章

  1. PTA - - 06-图1 列出连通集 (25分)

    06-图1 列出连通集   (25分) 给定一个有NN个顶点和EE条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N-1N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发, ...

  2. 图论——图的邻接表实现——Java语言(完整demo)

    1.图的简单实现方法——邻接矩阵 表示图的一种简单的方法是使用一个一维数组和一个二维数组,称为领接矩阵(adjacent matrix)表示法. 对于每条边(u,v),置A[u,v]等于true:否则 ...

  3. 【(图) 旅游规划 (25 分)】【Dijkstra算法】

    #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> us ...

  4. 1090 危险品装箱 (25分)C语言

    集装箱运输货物时,我们必须特别小心,不能把不相容的货物装在一只箱子里.比如氧化剂绝对不能跟易燃液体同箱,否则很容易造成爆炸. 本题给定一张不相容物品的清单,需要你检查每一张集装箱货品清单,判断它们是否 ...

  5. 1050 螺旋矩阵 (25 分)C语言

    本题要求将给定的 N 个正整数按非递增的顺序,填入"螺旋矩阵".所谓"螺旋矩阵",是指从左上角第 1 个格子开始,按顺时针螺旋方向填充.要求矩阵的规模为 m 行 ...

  6. 1065 单身狗 (25分)C语言

    单身狗"是中文对于单身人士的一种爱称.本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱. 输入格式: 输入第一行给出一个正整数 N(≤ 50 000),是已知夫妻/伴侣的对数:随 ...

  7. 1060 爱丁顿数 (25 分)C语言

    英国天文学家爱丁顿很喜欢骑车.据说他为了炫耀自己的骑车功力,还定义了一个"爱丁顿数" E ,即满足有 E 天骑车超过 E 英里的最大整数 E.据说爱丁顿自己的 E 等于87. 现给 ...

  8. 1025 反转链表 (25 分)C语言

    题目描述 给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转.例如:给定L为1→2→3→4→5→6,K为3,则输出应该为 3→2→1→6→5→4:如果K为4,则输出应该为4→3→2→1→5 ...

  9. 1055 集体照 (25 分)C语言

    拍集体照时队形很重要,这里对给定的 N 个人 K 排的队形设计排队规则如下: 每排人数为 N/K(向下取整),多出来的人全部站在最后一排: 后排所有人的个子都不比前排任何人矮: 每排中最高者站中间(中 ...

随机推荐

  1. slave IO流程之一:mysql登陆过程(mysql_real_connect)

    最近看了slave IO的源码,发现slave IO的写relay log貌似是单线程单连接的,这让我有点小失望. slave IO的主函数是handle_slave_io,处理流程如下: 图1 ha ...

  2. Sql Server系列:嵌套查询

    嵌套查询是指一个查询语句嵌套在另一个查询语句内部的查询.嵌套查询也就子查询,在SELECT子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或多个表.子查询中可以使用比较运 ...

  3. jQuery 2.0.3 源码分析 事件绑定 - bind/live/delegate/on

    事件(Event)是JavaScript应用跳动的心脏,通过使用JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应 事件的基础就不重复讲解了,本来是定位源码分析 ...

  4. Windows phone重写返回键

    protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) {//需要设置这个属性 e.Cancel ...

  5. Web APi入门之Self-Host寄宿及路由原理(二)

    前言 刚开始表面上感觉Web API内容似乎没什么,也就是返回JSON数据,事实上远非我所想,不去研究不知道,其中的水还是比较深,那又如何,一步一个脚印来学习都将迎刃而解. Self-Host 我们知 ...

  6. Ubuntu杂记——Apache+PHP+MySQL的安装

    昨天晚上,参考博客园的另一篇文章,在自己的Ubuntu上搭建了一个Apache+PHP+MySQL的服务器,在此谨记,以备不时之需. 一.安装Apache sudo apt-get install a ...

  7. spring源码分析之定时任务Scheduled注解

    1. @Scheduled 可以将一个方法标识为可定时执行的.但必须指明cron(),fixedDelay(),或者fixedRate()属性. 注解的方法必须是无输入参数并返回空类型void的. @ ...

  8. C#将一个excel工作表根据指定范围拆分为多个excel文件

    C#将一个excel工作表根据指定范围拆分为多个excel文件 微软Excel没有提供直接的方法来拆分excel文件,因此要拆分一个excel文件最简单的方法可能就是手动剪切和粘贴了,除此之外,还有其 ...

  9. 浅谈 php 采用curl 函数库获取网页 cookie 和 带着cookie去访问 网页的方法!!!!

    由于近段时间帮朋友开发一个能够查询正方教务系统的微信公众平台号.有所收获.这里总结下个人经验. 开讲前,先吐槽一下新浪云服务器,一个程序里的   同一个函数  在PC测试可以正常运行,在它那里就会挂的 ...

  10. 史上最详细的iOS之事件的传递和响应机制

    前言: 按照时间顺序,事件的生命周期是这样的: 事件的产生和传递(事件如何从父控件传递到子控件并寻找到最合适的view.寻找最合适的view的底层实现.拦截事件的处理)->找到最合适的view后 ...