DS第6章学习小结
一、谈谈你对本章的学习心得,或者任选本章一道题目,谈谈你解决该题的心得体会
图的存储结构,当下我们应当掌握得很透彻的,有两种,邻接矩阵和邻接表,
关于图的遍历方式,也有两种,深度优先搜索(DFS)和广度优先搜索(BFS)。
然后,PTA上 第7章作业7-1 列出连通集 很好的考察了DFS和BFS的具体实现。
首先是题目要求:
因为题目中有个比较坑的要求,
所以我推荐用邻接矩阵的存储结构去创建图。(如果用邻接表去整,还要将邻接表中的邻接点域按从小到大排,麻烦)

1 typedef struct 2 { 3 int **matrix;//邻接矩阵 4 int vexnum,arcnum;//顶点和边数 5 }Graph; 6 7 8 void CreateUDG(Graph &G);//创建无向图 9 void DFS(Graph G, int k);//深搜 10 void BFS(Graph G, int k);//广搜 11 void find(Graph G);//依次输出连通集,先DFS后BFS 12 13 14 bool v[100];
这是写代码前要想好的需要些什么结构体、函数、变量。
然后主函数:

1 int main() 2 { 3 Graph G; 4 CreateUDG(G); 5 6 7 find(G); 8 return 0; 9 }
然后各个函数的具体代码:

1 void CreateUDG(Graph &G)//创建无向图 2 { 3 cin>>G.vexnum>>G.arcnum;//输入顶点数和边数 4 5 6 G.matrix=new int*[G.vexnum];//动态创建邻接矩阵 7 for(int i=0; i<G.vexnum; i++) 8 { 9 G.matrix[i]=new int[G.vexnum]; 10 for(int j=0; j<G.vexnum; j++) 11 { 12 G.matrix[i][j]=0; 13 } 14 } 15 16 17 int a,b; 18 for(int i=0; i<G.arcnum; i++) 19 { 20 cin>>a>>b; 21 G.matrix[a][b]=1; 22 G.matrix[b][a]=1; 23 } 24 }

1 void DFS(Graph G, int k)//深搜 2 { 3 cout<<k<<' '; 4 v[k]=true; 5 for(int i=0; i<G.vexnum; i++) 6 { 7 if(G.matrix[k][i]==1 && !v[i]) 8 { 9 DFS(G,i); 10 } 11 } 12 }

1 void BFS(Graph G, int k)//广搜 2 { 3 queue<int> q; 4 q.push(k); 5 v[k]=true; 6 cout<<k<<' '; 7 8 9 while(!q.empty()) 10 { 11 int temp=q.front(); 12 q.pop(); 13 for(int i=0; i<G.vexnum; i++) 14 { 15 if(G.matrix[temp][i]==1 && !v[i]) 16 { 17 q.push(i); 18 v[i]=true; 19 cout<<i<<' '; 20 } 21 } 22 } 23 }

1 void find(Graph G)//依次输出连通集,先DFS后BFS 2 { 3 for(int i=0; i<G.vexnum; i++)//初始化v[i]数组 4 { 5 v[i]=false; 6 } 7 8 bool flag=true; 9 for(int i=0; i<G.vexnum; i++) 10 { 11 if(!flag && !v[i]) 12 { 13 cout<<endl<<'{'<<' '; 14 DFS(G,i); 15 cout<<'}'; 16 } 17 else if(flag && !v[i]) 18 { 19 cout<<'{'<<' '; 20 DFS(G,i); 21 cout<<'}'; 22 flag=false; 23 } 24 } 25 26 27 for(int i=0; i<G.vexnum; i++)//重置v[i]数组 28 { 29 v[i]=false; 30 } 31 32 for(int i=0; i<G.vexnum; i++) 33 { 34 if(!v[i]) 35 { 36 cout<<endl<<'{'<<' '; 37 BFS(G,i); 38 cout<<'}'; 39 } 40 } 41 }
第一次做这个题目的时候,我没有看到题目中最后一句话的要求,然后就用了邻接表去做,后面经过修改后虽然我感觉差不多,但是在PTA提交的时候有个段错误,应该是我太菜了,然后用邻接矩阵做就轻松很多了。
二、同时谈谈你对上次制定目标的完成情况
我自己也不太清楚对于上次目标的完成情况是怎样的,感觉对于图的一些操作的具体实现还不算了然于心,甚至第六章的内容好像也读的不是很透彻,还是要继续努力才是。
三、以及接下来的目标
之后好像还有两章要学,那就学好之后的两章,还有要对这一章图的一些操作的具体实现要更加深刻才行。
附上列出连通集的菜鸡代码(邻接矩阵)(只作记录,不要当成是作业内容):

1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 5 6 typedef struct 7 { 8 int **matrix;//邻接矩阵 9 int vexnum,arcnum;//顶点和边数 10 }Graph; 11 12 13 14 15 void CreateUDG(Graph &G);//创建无向图 16 void DFS(Graph G, int k);//深搜 17 void BFS(Graph G, int k);//广搜 18 void find(Graph G);//依次输出连通集,先DFS后BFS 19 20 21 22 23 bool v[100]; 24 int main()//列出连通集 25 { 26 Graph G; 27 CreateUDG(G); 28 29 30 find(G); 31 32 33 /* for(int i=0; i<8; i++) 34 { 35 for(int j=0; j<8; j++) 36 { 37 cout<<G.matrix[i][j]<<' '; 38 } 39 cout<<endl; 40 }*/ 41 42 43 return 0; 44 } 45 46 47 48 49 void CreateUDG(Graph &G)//创建无向图 50 { 51 cin>>G.vexnum>>G.arcnum;//输入顶点数和边数 52 53 54 G.matrix=new int*[G.vexnum];//动态创建邻接矩阵 55 for(int i=0; i<G.vexnum; i++) 56 { 57 G.matrix[i]=new int[G.vexnum]; 58 for(int j=0; j<G.vexnum; j++) 59 { 60 G.matrix[i][j]=0; 61 } 62 } 63 64 65 int a,b; 66 for(int i=0; i<G.arcnum; i++) 67 { 68 cin>>a>>b; 69 G.matrix[a][b]=1; 70 G.matrix[b][a]=1; 71 } 72 } 73 74 75 void DFS(Graph G, int k)//深搜 76 { 77 cout<<k<<' '; 78 v[k]=true; 79 for(int i=0; i<G.vexnum; i++) 80 { 81 if(G.matrix[k][i]==1 && !v[i]) 82 { 83 DFS(G,i); 84 } 85 } 86 } 87 88 89 void BFS(Graph G, int k)//广搜 90 { 91 queue<int> q; 92 q.push(k); 93 v[k]=true; 94 cout<<k<<' '; 95 96 97 while(!q.empty()) 98 { 99 int temp=q.front(); 100 q.pop(); 101 for(int i=0; i<G.vexnum; i++) 102 { 103 if(G.matrix[temp][i]==1 && !v[i]) 104 { 105 q.push(i); 106 v[i]=true; 107 cout<<i<<' '; 108 } 109 } 110 } 111 } 112 113 114 void find(Graph G)//依次输出连通集,先DFS后BFS 115 { 116 for(int i=0; i<G.vexnum; i++)//初始化v[i]数组 117 { 118 v[i]=false; 119 } 120 121 bool flag=true; 122 for(int i=0; i<G.vexnum; i++) 123 { 124 if(!flag && !v[i]) 125 { 126 cout<<endl<<'{'<<' '; 127 DFS(G,i); 128 cout<<'}'; 129 } 130 else if(flag && !v[i]) 131 { 132 cout<<'{'<<' '; 133 DFS(G,i); 134 cout<<'}'; 135 flag=false; 136 } 137 } 138 139 140 for(int i=0; i<G.vexnum; i++)//重置v[i]数组 141 { 142 v[i]=false; 143 } 144 145 for(int i=0; i<G.vexnum; i++) 146 { 147 if(!v[i]) 148 { 149 cout<<endl<<'{'<<' '; 150 BFS(G,i); 151 cout<<'}'; 152 } 153 } 154 }
附上拯救007的菜鸡代码(邻接矩阵)(只作记录,不要当成是作业内容):

1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 5 6 typedef struct 7 { 8 int x,y; 9 }data; 10 11 12 typedef struct 13 { 14 int vexnum;//顶点数 15 int max;//007一次能跳跃的最大距离 16 data *vex;//顶点表 17 int **matrix;//邻接矩阵 18 }Graph; 19 20 21 22 23 void create(Graph &G);//动态创建邻接矩阵 24 bool low(Graph G, data a, data b);//判断两点是否能相连 25 bool finish(Graph G, data a);//判断007是否能从该点一步跳出鳄鱼池 26 bool BFS_find(Graph G, int k);//判断007从该点是否能成功逃生 27 bool start(Graph G, int k);//判断该点能否作为起点 28 bool find(Graph G); 29 30 31 32 33 bool *v; 34 int main() 35 { 36 Graph G; 37 create(G); 38 39 40 /* for(int i=0; i<G.vexnum; i++) 41 { 42 for(int j=0; j<G.vexnum; j++) 43 { 44 cout<<G.matrix[i][j]<<' '; 45 } 46 cout<<endl; 47 }*/ 48 49 50 v=new bool[G.vexnum]; 51 for(int i=0; i<G.vexnum; i++) 52 { 53 v[i]=false; 54 } 55 56 57 if(find(G)) 58 { 59 cout<<"Yes"; 60 } 61 else 62 { 63 cout<<"No"; 64 } 65 66 67 return 0; 68 } 69 70 71 72 73 void create(Graph &G)//动态创建邻接矩阵 74 { 75 cin>>G.vexnum>>G.max;//输入点的个数和一次能跳跃的最大距离 76 G.vex=new data[G.vexnum]; 77 78 79 G.matrix=new int*[G.vexnum]; 80 for(int i=0; i<G.vexnum; i++) 81 { 82 cin>>G.vex[i].x>>G.vex[i].y;//在顶点表中录入每个点的具体坐标 83 84 85 G.matrix[i]=new int[G.vexnum]; 86 for(int j=0; j<G.vexnum; j++) 87 { 88 G.matrix[i][j]=0; 89 } 90 } 91 92 93 for(int i=0; i<G.vexnum; i++) 94 { 95 for(int j=i+1; j<G.vexnum; j++) 96 { 97 if(low(G,G.vex[i],G.vex[j])) 98 { 99 G.matrix[i][j]=1; 100 G.matrix[j][i]=1; 101 } 102 } 103 } 104 } 105 106 107 bool low(Graph G, data a, data b)//判断两点是否能连起来 108 { 109 if((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)<G.max*G.max) 110 { 111 return true; 112 } 113 else 114 { 115 return false; 116 } 117 } 118 119 120 bool finish(Graph G, data vex)//判断007是否能从该点一步跳出鳄鱼池 121 { 122 if(vex.x<0) vex.x=-vex.x; 123 if(vex.y<0) vex.y=-vex.y; 124 if(50-vex.x<=G.max || 50-vex.y<=G.max) 125 { 126 return true; 127 } 128 else 129 { 130 return false; 131 } 132 } 133 134 135 bool BFS_find(Graph G, int k)//判断007从该点是否能成功逃生 136 { 137 queue<int> q; 138 q.push(k); 139 v[k]=true; 140 141 142 while(!q.empty()) 143 { 144 int tmp=q.front(); 145 q.pop(); 146 147 148 if(finish(G,G.vex[tmp]))//判断007是否能从该点一步跳出鳄鱼池 149 { 150 return true; 151 } 152 153 for(int i=0; i<G.vexnum; i++) 154 { 155 if(!v[i] && G.matrix[tmp][i]==1) 156 { 157 q.push(i); 158 v[i]=true; 159 } 160 } 161 162 163 } 164 return find(G); 165 } 166 167 168 bool start(Graph G, int k)//判断该点能否作为起点 169 { 170 if(G.vex[k].x*G.vex[k].x+G.vex[k].y*G.vex[k].y<=(G.max+7.5)*(G.max+7.5)) 171 { 172 return true; 173 } 174 else 175 { 176 return false; 177 } 178 } 179 180 181 bool find(Graph G)//判断007是否能成功逃生 182 { 183 if(G.max>=50-7.5) 184 { 185 return true; 186 } 187 188 189 for(int i=0; i<G.vexnum; i++) 190 { 191 if(!v[i] && start(G,i)) 192 { 193 return BFS_find(G,i); 194 } 195 } 196 197 198 return false; 199 }
附上拯救007的菜鸡代码(邻接表)(只作记录,不要当成是作业内容):

1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 5 6 typedef struct 7 { 8 int x,y; 9 }data; 10 11 12 typedef struct node 13 { 14 int adjvex; 15 node *next; 16 }node; 17 18 19 typedef struct 20 { 21 data vex; 22 node *first; 23 }list; 24 25 26 typedef struct 27 { 28 int vexnum;//顶点个数 29 int max;//007一次能跳跃的最大距离 30 list *vertices;//邻接表 31 }Graph; 32 33 34 35 36 void creat(Graph &G);//动态创建邻接表 37 bool low(Graph G, data a, data b);//判断两点是否能连起来 38 bool finish(Graph G, data a);//判断007是否能从该点一步跳出鳄鱼池 39 bool BFS_find(Graph G, int k);//判断007从该点是否能成功逃生 40 bool start(Graph G, int k);//判断该点能否作为起点 41 bool find(Graph G);//判断007是否能成功逃生 42 43 44 45 46 bool *v; 47 int main()//拯救007 48 { 49 Graph G; 50 creat(G); 51 52 53 /* for(int i=0; i<G.vexnum; i++) 54 { 55 node *p=G.vertices[i].first; 56 cout<<'<'<<G.vertices[i].vex.x<<','<<G.vertices[i].vex.y<<'>'<<' '<<' '; 57 while(p!=NULL) 58 { 59 cout<<'<'<<G.vertices[p->adjvex].vex.x<<','<<G.vertices[p->adjvex].vex.y<<'>'<<' '<<' '; 60 p=p->next; 61 } 62 cout<<endl; 63 }*/ 64 65 66 v=new bool[G.vexnum]; 67 for(int i=0; i<G.vexnum; i++) 68 { 69 v[i]=false; 70 } 71 72 73 if(find(G)) 74 { 75 cout<<"Yes"; 76 } 77 else 78 { 79 cout<<"No"; 80 } 81 82 83 return 0; 84 } 85 86 87 void creat(Graph &G)//动态创建邻接表 88 { 89 cin>>G.vexnum>>G.max;//输入点的个数和一次能跳跃的最大距离 90 G.vertices=new list[G.vexnum]; 91 92 93 for(int i=0; i<G.vexnum; i++)//在邻接表中录入每个点的具体坐标 94 { 95 cin>>G.vertices[i].vex.x>>G.vertices[i].vex.y; 96 G.vertices[i].first=NULL; 97 } 98 99 100 for(int i=0; i<G.vexnum; i++)//将可以连的点相连起来 101 { 102 for(int j=i+1; j<G.vexnum; j++) 103 { 104 if(low(G,G.vertices[i].vex,G.vertices[j].vex)) 105 { 106 node *p=new node; 107 p->next=G.vertices[i].first; 108 G.vertices[i].first=p; 109 p->adjvex=j; 110 111 node *q=new node; 112 q->next=G.vertices[j].first; 113 G.vertices[j].first=q; 114 q->adjvex=i; 115 } 116 } 117 } 118 } 119 120 121 bool low(Graph G, data a, data b)//判断两点是否能连起来 122 { 123 if((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)<=G.max*G.max) 124 { 125 return true; 126 } 127 else 128 { 129 return false; 130 } 131 } 132 133 134 bool finish(Graph G, data vex)//判断007是否能从该点一步跳出鳄鱼池 135 { 136 if(vex.x<0) vex.x=-vex.x; 137 if(vex.y<0) vex.y=-vex.y; 138 if(50-vex.x<=G.max || 50-vex.y<=G.max) 139 { 140 return true; 141 } 142 else 143 { 144 return false; 145 } 146 } 147 148 149 bool BFS_find(Graph G, int k)//判断007从该点是否能成功逃生 150 { 151 queue<int> q; 152 q.push(k); 153 v[k]=true; 154 155 156 while(!q.empty()) 157 { 158 int tmp=q.front(); 159 q.pop(); 160 161 162 if(finish(G,G.vertices[tmp].vex))//判断007是否能从该点一步跳出鳄鱼池 163 { 164 return true; 165 } 166 167 168 node *p=G.vertices[tmp].first; 169 while(p!=NULL) 170 { 171 if(!v[p->adjvex]) 172 { 173 q.push(p->adjvex); 174 v[p->adjvex]=true; 175 } 176 p=p->next; 177 } 178 } 179 return find(G); 180 } 181 182 183 bool start(Graph G, int k)//判断该点能否作为起点 184 { 185 if(G.vertices[k].vex.x*G.vertices[k].vex.x+G.vertices[k].vex.y*G.vertices[k].vex.y<=(G.max+7.5)*(G.max+7.5)) 186 { 187 return true; 188 } 189 else 190 { 191 return false; 192 } 193 } 194 195 196 bool find(Graph G)//判断007是否能成功逃生 197 { 198 if(G.max>=50-7.5) 199 { 200 return true; 201 } 202 203 204 for(int i=0; i<G.vexnum; i++) 205 { 206 if(!v[i] && start(G,i)) 207 { 208 return BFS_find(G,i); 209 } 210 } 211 212 213 return false; 214 }