題目地址: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