学习心得:每节课学了的知识,课后需要做题巩固一下,不然对一些定义不是很清楚,易混淆,而且对很多知识的理解非常模糊,就像上次小测的那个哈夫曼树的表一样,我当时没复习哈夫曼树的表,所以考试时完全写不出来,但是后来看书发现自己早就知道怎么写,只不过当时老师讲的时候不知道那个就叫哈夫曼树的表。
这一章我想讲一下 7-1列出连通集 这道题(因为实践还没写出来)
这道题我的解题思路为:
1.用邻接矩阵来表示无向非连通图
2.分别写出DFS,BFS的遍历代码
因为顶点的名字本身就是顶点的下标,所以我的结构体定义如下
typedef struct { int arcs[10][10]; int vexnum,arcnum; }AMgraph;
我没有在结构体定义顶点表
然后就是构造一个图的函数了
void CreateUDN(AMgraph &G) {//构建一个邻接矩阵来存储边 cin>>G.vexnum>>G.arcnum; for(int i=0;i<G.vexnum;++i) { for(int j=0;j<G.vexnum;++j) { G.arcs[i][j]=0; } } for(int k=0;k<G.arcnum;++k) {//两个 顶点之间有边,则·其对应矩阵的下标值改为1,无则为0 int v1,v2; cin>>v1>>v2; G.arcs[v1][v2]=1; G.arcs[v2][v1]= G.arcs[v1][v2]; } }
邻接矩阵全部初始化为0了
因为visited函数不是全局定义,所以我在主函数中的BFS和DFS调用中加上了调用visited函数的代码
int main() { AMgraph G; CreateUDN(G); bool visited[10];//访问标志数组,其初始值为false for(int v=0;v<G.vexnum;++v) visited[v]=false; DFSTraverse(G,visited); for(int v=0;v<G.vexnum;++v) visited[v]=false; BFSTraverse(G,visited); return 0; }
我用DFSTraverse函数循环调用DFS算法并依次输出联通集
void BFS (AMgraph G, int v,bool visited[]) { //按广度优先非递归遍历连通图G int t; queue<int> q; visited[v]=true; q.push(v); while(!q.empty()) {//利用队列对邻接矩阵进行广度优先访问 t=q.front(); cout<<t<<" "; q.pop(); for(int w=0;w<G.vexnum;w++) { if((G.arcs[t][w]!=0)&&(!visited[w])) {//当顶点之间有边,并且未被访问过,再次调用BFS进行访问 visited[w]=true; q.push(w); } } } }//BFS void BFSTraverse(AMgraph G,bool visited[]) { for(int p=0;p<G.vexnum;++p) {//循环调用BFS直到每一个联通分量皆被访问完 if(!visited[p]) { cout<<"{ "; BFS(G,p,visited); cout<<"}"<<endl; } } }
BFS算法中使用了队列来进行广搜,我一开始是想参照书上的来打BFS函数的代码,但是后来问了同学有更加简便的方法后,就采用了她那种方法了,其实两种都是借用了队列,我的这段代码可以直接调用函数库,不用再写函数,比较像之前第五章的listleaves那道中的层次遍历函数的写法
完整代码如下
#include <iostream> #include <queue> using namespace std; typedef struct { int arcs[10][10]; int vexnum,arcnum; }AMgraph; void DFS(AMgraph G,int v,bool visited[]); void DFSTraverse(AMgraph G,bool visited[]); void BFS (AMgraph G, int v,bool visited[]); void BFSTraverse(AMgraph G,bool visited[]); void CreateUDN(AMgraph &G) {//构建一个邻接矩阵来存储边 cin>>G.vexnum>>G.arcnum; for(int i=0;i<G.vexnum;++i) { for(int j=0;j<G.vexnum;++j) { G.arcs[i][j]=0; } } for(int k=0;k<G.arcnum;++k) {//两个 顶点之间有边,则·其对应矩阵的下标值改为1,无则为0 int v1,v2; cin>>v1>>v2; G.arcs[v1][v2]=1; G.arcs[v2][v1]= G.arcs[v1][v2]; } } int main() { AMgraph G; CreateUDN(G); bool visited[10];//访问标志数组,其初始值为false for(int v=0;v<G.vexnum;++v) visited[v]=false; DFSTraverse(G,visited); for(int v=0;v<G.vexnum;++v) visited[v]=false; BFSTraverse(G,visited); return 0; } void DFS(AMgraph G,int v,bool visited[]) {//从第v个顶点出发递归深度优先遍历图G cout<<v<<" "; visited[v]=true; for(int w=0;w<G.vexnum;w++) { if((G.arcs[v][w]!=0)&&(!visited[w])) DFS(G,w,visited);//当顶点之间有边,并且未被访问过,再次调用DFS进行访问 } } void DFSTraverse(AMgraph G,bool visited[]) { for(int p=0;p<G.vexnum;++p) {//循环调用DFS直到每一个联通分量皆被访问完 if(!visited[p]) { cout<<"{ "; DFS(G,p,visited); cout<<"}"<<endl; } } } void BFS (AMgraph G, int v,bool visited[]) { //按广度优先非递归遍历连通图G int t; queue<int> q; visited[v]=true; q.push(v); while(!q.empty()) {//利用队列对邻接矩阵进行广度优先访问 t=q.front(); cout<<t<<" "; q.pop(); for(int w=0;w<G.vexnum;w++) { if((G.arcs[t][w]!=0)&&(!visited[w])) {//当顶点之间有边,并且未被访问过,再次调用BFS进行访问 visited[w]=true; q.push(w); } } } }//BFS void BFSTraverse(AMgraph G,bool visited[]) { for(int p=0;p<G.vexnum;++p) {//循环调用BFS直到每一个联通分量皆被访问完 if(!visited[p]) { cout<<"{ "; BFS(G,p,visited); cout<<"}"<<endl; } } }
浙公网安备 33010602011771号