06-图1 列出连通集 (25分)(C语言邻接表实现)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了06-图1 列出连通集 (25分)(C语言邻接表实现)相关的知识,希望对你有一定的参考价值。

题目地址: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);
            }
    } 
}        

具体代码

技术分享
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <stdbool.h>
  4 #include <string.h>
  5 #include <dos.h>
  6 
  7 #define MaxVertexNum 10
  8 
  9 typedef int ElementType;
 10 typedef int Position;
 11 
 12 typedef struct QNode {
 13     ElementType *Data;     /* 存储元素的数组 */
 14     Position Front, Rear;  /* 队列的头、尾指针 */
 15     int MaxSize;           /* 队列最大容量 */
 16 }QNode, *Queue;
 17 
 18 
 19 typedef struct ENode
 20 {
 21     int ivex;            //该边指向的顶点位置
 22     struct ENode * next;     
 23 }ENode, *PENode;
 24 
 25 typedef int VertexType; 
 26 
 27 typedef struct VNode
 28 {
 29     VertexType data;
 30     ENode * first_edge;
 31 }VNode;
 32 
 33 typedef struct LGraph
 34 {
 35     int vexnum;            //图的顶点数目
 36     int edgnum;            //图的边的数目
 37     VNode * vexs;       //存放顶点的数组
 38 }LGraph;
 39 
 40 bool TAG;                   //用于输出格式
 41 bool visited[MaxVertexNum];
 42 
 43 LGraph * LGraph_new();
 44 void LGraph_destroy(LGraph * G);
 45 void LGraph_insert(ENode ** head, int ivex);
 46 void ResetVisit();
 47 void DFS(LGraph * G, int vex);
 48 void BFS(LGraph * G, int vex);
 49 void ListComponents(LGraph * G, void (*func)(LGraph * G, int vex));
 50 
 51 //优先队列的基本操作
 52 Queue CreateQueue( int MaxSize );
 53 bool IsFull( Queue Q );
 54 bool AddQ( Queue Q, ElementType X );
 55 bool IsEmpty( Queue Q );
 56 ElementType DeleteQ( Queue Q );
 57 
 58 int main()
 59 {
 60     LGraph * G = LGraph_new();
 61     ResetVisit();
 62     ListComponents(G, DFS);
 63     ResetVisit();
 64     ListComponents(G, BFS);
 65     system("pause");
 66     return 0;
 67 }
 68 
 69 void ListComponents(LGraph * G, void (*func)(LGraph * G, int vex))
 70 {
 71     int i;
 72     for ( i = 0; i < G->vexnum; ++i )
 73     {
 74         if (visited[i] == false)
 75         {
 76             (*func)(G, i);
 77             printf("}\\n");
 78             TAG = false;
 79         }
 80     }
 81 }
 82 
 83 LGraph * LGraph_new()
 84 {
 85 
 86     LGraph * G = (LGraph *)malloc(sizeof(LGraph));
 87     scanf("%d %d", &G->vexnum, &G->edgnum);
 88     G->vexs = (VNode *)malloc(G->vexnum * sizeof(VNode));
 89     int i, v1, v2;
 90     for ( i = 0; i < G->vexnum; ++i )
 91     {
 92         G->vexs[i].data = i;
 93         G->vexs[i].first_edge = NULL;
 94     }
 95     for ( i = 0; i < G->edgnum; ++i )
 96     {
 97         scanf("%d %d", &v1, &v2);
 98         //由于顶点信息就是顶点坐标
 99         LGraph_insert(&G->vexs[v1].first_edge, v2);
100         LGraph_insert(&G->vexs[v2].first_edge, v1);
101     }
102     return G;
103 }
104 
105 void ResetVisit()
106 {
107     TAG = false;
108     memset(visited, false, sizeof(visited));
109 }
110 
111 void LGraph_insert(ENode ** head, int ivex)
112 {
113     ENode *pnew, *p1, *p2;
114     pnew = (ENode *)malloc(sizeof(ENode));
115     pnew->ivex = ivex;
116     if ( *head == NULL )
117     {
118         *head = pnew;
119         
120         pnew->next = NULL;
121     }
122     else 
123     {
124         if ( (*head)->ivex > ivex ) //没头结点的麻烦
125         {
126             pnew->next = *head;
127             *head = pnew;
128         }
129         else
130         {
131             for (p1 = *head,    p2 = p1->next; p2 != NULL ; p1 = p2, p2 = p1->next )
132             {
133                 if ( p2->ivex > ivex )
134                     break;
135             }
136             pnew->next = p2;
137             p1->next = pnew;
138         }
139     }
140 }
141 
142 void DFS(LGraph * G, int vex)
143 {
144     if (TAG == false)
145     {
146         TAG = true;
147         printf("{ ");
148     }
149     printf("%d ", vex);
150     visited[vex] = true;
151     ENode * temp = G->vexs[vex].first_edge;
152     while( temp != NULL )
153     {
154         if (visited[temp->ivex] == false)
155         {
156              DFS(G, temp->ivex);
157         }
158         temp = temp->next;
159     }
160 }
161 void BFS(LGraph * G, int vex)
162 {
163     Queue Q = CreateQueue(G->vexnum);
164     if (TAG == false)
165     {
166         TAG = true;
167         printf("{ ");
168     }
169     printf("%d ", vex);
170     visited[vex] = true;
171     AddQ(Q, vex);
172     while (!IsEmpty(Q))
173     {
174         vex = DeleteQ(Q);
175         ENode * temp = G->vexs[vex].first_edge;
176         while (temp != NULL)
177         {
178             if ( visited[temp->ivex] == false )
179             {
180                 printf("%d ",temp->ivex);
181                 visited[temp->ivex] = true;
182                 AddQ(Q, temp->ivex);
183             }
184             temp = temp->next;
185         }
186     }
187     free(Q->Data);
188     free(Q);
189 }
190 
191 
192 //队列基本操作
193 Queue CreateQueue( int MaxSize )
194 {
195     Queue Q = (Queue)malloc(sizeof(struct QNode));
196     Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
197     Q->Front = Q->Rear = 0;
198     Q->MaxSize = MaxSize;
199     return Q;
200 }
201  
202 bool IsFull( Queue Q )
203 {
204     return ((Q->Rear+1)%Q->MaxSize == Q->Front);
205 }
206  
207 bool AddQ( Queue Q, ElementType X )
208 {
209     if ( IsFull(Q) ) {
210         printf("队列满");
211         return false;
212     }
213     else {
214         Q->Rear = (Q->Rear+1)%Q->MaxSize;
215         Q->Data[Q->Rear] = X;
216         return true;
217     }
218 }
219  
220 bool IsEmpty( Queue Q )
221 {
222     return (Q->Front == Q->Rear);
223 }
224  
225 ElementType DeleteQ( Queue Q )
226 {
227     if ( IsEmpty(Q) ) { 
228         printf("队列空");
229         return 0;
230     }
231     else  {
232         Q->Front =(Q->Front+1)%Q->MaxSize;
233         return  Q->Data[Q->Front];
234     }
235 }
View Code

 

以上是关于06-图1 列出连通集 (25分)(C语言邻接表实现)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

列出连通集

7-1 列出连通集 (25 分)